Home
Guide
English
简体中文
Home
Guide
English
简体中文

Quick Guide

ue-connect Documentation

#UE-Connect Documentation

#1. Overview

ue-connect is a Unreal Engine 5 (UE5) connector module designed specifically for QuickUIDesign applications. It provides a complete set of hooks and context management tools, enabling ue-connect to establish bidirectional communication with UE5, particularly suitable for developing UE5 interactive interfaces based on QuickUIDesign.

QuickUIDesign is a React-based interface template that allows developers to easily create feature-rich interactive interfaces in UE5.

#2. Installation

  • Copy the ue-connect library files into your project
  • Configure package.json to add the ue-connect library reference
{
  "dependencies": {
    "ue-connect": "./ue-connect",
  }
}

#3. Core Features

#3.1 Context Management

#UEProvider and useUEContext

Provides global UE5 connection state management.

import { UEProvider, useUEContext } from 'ue-connect'

// Provide context at the app root component
function App() {
  return (
    <UEProvider>
      <YourComponent />
    </UEProvider>
  )
}

// Use context in child components
function YourComponent() {
  const { isConnected, isMobile, useMouse, setUseMouse, lastKeyAction } = useUEContext()

  return (
    <div>
      <p>Connection Status: {isConnected ? 'Connected' : 'Disconnected'}</p>
      <p>Device Type: {isMobile ? 'Mobile' : 'Desktop'}</p>
      <p>Last Key Action: {lastKeyAction || 'None'}</p>
      <button onClick={() => setUseMouse(!useMouse)}>{useMouse ? 'Disable Mouse' : 'Enable Mouse'}</button>
    </div>
  )
}

Return Values:

  • isConnected: Indicates whether connected to the UE5 window
  • isMobile: Indicates whether it is a mobile device
  • useMouse: Indicates whether mouse events are enabled
  • setUseMouse: Function to enable/disable mouse events
  • lastKeyAction: Last key action from UE5 input events. Values: "Up" | "Down" | "Left" | "Right" | "Next" | "Previous" | "Select" | null

UEProvider Notes:

UEProvider internally integrates mouse event management (useUEMouse) and input event listening (useInputKeyEventListener). Child components can directly access connection status, device type, mouse status, and last key action through useUEContext.

#3.2 QuickUI Custom Event System

#useQuickUIEventSender and useQuickUIEventListener

Implements custom event communication between Web and UE5. Users can design their own event names and JSON formats.

  • useQuickUIEventSender is used to send events, requires specifying the event name (corresponds to backend QuickUIListenEvent)
  • useQuickUIEventListener is used to listen for events, requires specifying the event name (corresponds to backend QuickUIEventCallBack)
import { useQuickUIEventSender, useQuickUIEventListener } from 'ue-connect'

function EventSystemComponent() {
  // Send event - requires specifying event name (corresponds to backend QuickUIListenEvent)
  const sendEvent = useQuickUIEventSender('playerUpdate')

  // Listen for events from UE (corresponds to backend QuickUIEventJSONGenerate)
  useQuickUIEventListener('gameStateChange', (event) => {
    console.log('Game state changed:', event)
    console.log('Event topic:', event.topic)
    console.log('Event payload:', event.payload)
    console.log('Timestamp:', event.timestamp)
    console.log('Event source:', event.source) // "web" or "ue"
  })

  const updatePlayer = () => {
    // Send event to UE (fire-and-forget)
    sendEvent({
      health: 100,
      ammo: 30,
      position: { x: 10, y: 20, z: 30 }
    })
  }

  return <button onClick={updatePlayer}>Update Player Data</button>
}

useQuickUIEvent Parameters:

  • fnName: Event name (corresponds to Blueprint / UMG event name)
  • Returns: A function to send events, accepting payload?: QuickEventPayload parameter

useQuickUIEventListener Parameters:

  • fnName: Event name (corresponds to Blueprint / UMG event name)
  • handler: Event handler function, receives QuickEvent object
    • event.type: Event type (fixed as "event")
    • event.topic: Event topic/name
    • event.payload: Event payload data
    • event.timestamp: Event timestamp
    • event.source: Event source ("web" or "ue")

#3.3 Mouse Event Management

#useUEMouse

  • Manages mouse event interaction with UE5, supports automatic detection of disabled areas.
  • data-nohit attribute: Used to mark element areas that should not trigger mouse events
import { useUEMouse } from 'ue-connect'

function MouseComponent() {
  const { useMouse, setUseMouse } = useUEMouse(true)

  return (
    <div>
      <button onClick={() => setUseMouse(!useMouse)}>{useMouse ? 'Disable Mouse Events' : 'Enable Mouse Events'}</button>

      {/* This area will not trigger mouse events */}
      <div data-nohit style={{ padding: '20px', background: '#f0f0f0' }}>
        Mouse Event Disabled Area
      </div>
    </div>
  )
}

Features:

  • Automatically detects elements with data-nohit attribute
  • Automatically disables mouse events when hovering over disabled areas
  • Supports mobile device pixel ratio adaptation

#3.4 Game Control

#useUEGameControl

Provides game control functions such as quitting the game and executing console commands.

import { useUEGameControl } from 'ue-connect'

function GameControlComponent() {
  const gameControl = useUEGameControl()

  return (
    <div>
      <button onClick={() => gameControl.quitGame()}>Quit Game</button>
      <button onClick={() => gameControl.executeCommand('stat fps')}>Show FPS</button>
      <button onClick={() => gameControl.clientTravel('127.0.0.1')}>Connect to Server</button>
    </div>
  )
}

Available Methods:

  • quitGame(): Quit the game
  • executeCommand(command: string): Execute console command
  • clientTravel(address: string): Client travel to specified address
  • getGraphics(): Get graphics settings
  • applyAndSaveGraphics(...): Apply and save graphics settings

#3.5 Device Adaptation

#useDevicePixelRatio

Automatically adapts device pixel ratio for consistent display across different devices.

import { useDevicePixelRatio } from 'ue-connect'

function ResponsiveComponent() {
  const dpr = useDevicePixelRatio()

  return (
    <div
      style={{
        width: `${100 * dpr}px`,
        height: `${50 * dpr}px`
      }}
    >
      Adaptive Element
    </div>
  )
}

#3.6 Input Management

#useInputBlocker

Manages input event blocking to prevent accidental interactions.

import { useInputBlocker } from 'ue-connect'

function InputComponent() {
  const { blockInput, unblockInput, isBlocked } = useInputBlocker()

  return (
    <div>
      <button onClick={blockInput}>Block Input</button>
      <button onClick={unblockInput}>Allow Input</button>
      <p>Current Status: {isBlocked ? 'Input Blocked' : 'Input Normal'}</p>
    </div>
  )
}

#useInputKeyEventListener

Listens to key navigation events sent by UE5 engine (Up/Down/Left/Right/Confirm/Next/Previous), suitable for TV or gamepad remote control scenarios without mouse input.

import { useInputKeyEventListener } from 'ue-connect'

function NavigationComponent() {
  const { lastKeyAction } = useInputKeyEventListener({
    onKeyAction: (action) => {
      console.log('Key Action:', action)
      // action values: "Up" | "Down" | "Left" | "Right" | "Next" | "Previous" | "Select"
    }
  })

  return (
    <div>
      <p>Last Key Action: {lastKeyAction || 'None'}</p>
    </div>
  )
}

Parameters:

  • options.onKeyAction (optional): Key event callback function, receives KeyAction type parameter

Return Values:

  • lastKeyAction: Last key action, values: "Up" | "Down" | "Left" | "Right" | "Next" | "Previous" | "Select" | null

Registered Global Functions:

This Hook registers the following global functions on the window object for UE5 to call via ExecuteJs:

Global Function NameTriggered KeyAction
window.keyUp"Up"
window.keyDown"Down"
window.keyLeft"Left"
window.keyRight"Right"
window.keyNext"Next"
window.keyPrev"Previous"
window.keyEventChoose"Select"

Automatically cleans up registered global functions when component unmounts.

#useUEEventJSON

Sends JSON-formatted event data to UE5.

import { useUEEventJSON } from 'ue-connect'

function EventComponent() {
  const triggerEvent = useUEEventJSON({ functionName: 'MyBlueprintEvent' })

  const handleClick = () => {
    triggerEvent({
      playerName: 'Player1',
      score: 100,
      level: 5,
      items: ['item1', 'item2']
    })
  }

  return <button onClick={handleClick}>Send Game Event</button>
}

Parameters:

  • functionName: Event name registered in UE5 Blueprint
  • Supports complex nested JSON data structures

#useUECallback (Legacy)

Optimized callback management that only triggers when the backend actually sends new data, avoiding unnecessary repeated calls.

import { useUECallback } from 'ue-connect'

function CallbackComponent() {
  useUECallback('OnPlayerDataUpdated', (onData) => {
    console.log('Player data updated:', onData)
    // Process player data
  })

  return <div>Callback Component</div>
}

Parameters:

  • functionName: Callback function name (custom agreed function name in UE5)
  • onData: Data processing callback function, data sent by UE5

Features:

  • Performance Optimized: Only triggers callback when backend actually sends new data
  • Auto Management: Registers global function on mount, auto-cleans on unmount
  • Stable Reference: Uses ref to maintain stable callback reference, avoiding frequent re-registration

#3.8 Utility Functions

#filterUECallBackJSonData

A general-purpose filtering function paired with useUECallback for processing UE callback JSON data, supporting filtering and property selection.

Method Signature:

function filterUECallBackJSonData<T extends Record<string, any>>(
  data: T | undefined,
  filters: Record<string, any>
): Partial<T> | undefined

Parameters:

  • data: UE callback JSON data to process
  • filters: Filter condition object, key is property name, value is filter value or filter function

Return Value:

  • Filtered data object, returns undefined if no match

Usage Example (with useUECallback):

import { useUECallback, filterUECallBackJSonData } from 'ue-connect'
import { useState } from 'react'

function AuthComponent() {
  useUECallback(
    'OnPlayerDataUpdated',
    (data) => {
      // First check if the returned data is a JSON string
      if (typeof data === 'string') {
        try {
          data = JSON.parse(data)
        } catch {
          console.error('Invalid JSON string, treating as non-JSON:', data)
          return
        }
      }
    
      // Filter data
      const filter = filterUECallBackJSonData(data, { health: (vs: any) => vs, isAlive: (vs: any) => vs })
      
      // Callback logic processing
      console.log('Filtered data:', filter)
      /*
      Output:
      Filtered data: { health: 100, isAlive: true }
      */
    }
  )

  return (
    <div>
      <p>Health: {filter?.health || 'N/A'}</p>
      <p>Alive: {filter?.isAlive ? 'Yes' : 'No'}</p>
    </div>
  )
}

Features:

  • Flexible Filtering: Supports filtering using functions or values
  • Type Safe: Supports TypeScript generics for type consistency
  • Auto Cleanup: Returns undefined when no matching properties, convenient for subsequent processing
  • Perfect with useUECallback: Simplifies data processing logic in callback handling

#4. Complete Example

import React from 'react'
import {
  UEProvider,
  useUEContext,
  useUEEventJSON,
  useUEMouse,
  useQuickUIEvent,
  useQuickUIEventListener,
  useUECallback,
  useInputKeyEventListener,
  filterUECallBackJSonData,
} from 'ue-connect'

function GameUI() {
  const { isConnected, useMouse, lastKeyAction } = useUEContext()
  const { useMouse: mouseEnabled, setUseMouse } = useUEMouse(true)
  const triggerEvent = useUEEventJSON({ functionName: 'UpdateUI' })

  // Use updated useQuickUIEvent
  const sendPlayerEvent = useQuickUIEvent('playerAction')
  const sendGameEvent = useQuickUIEvent('gameState')

  // Listen for events from UE5
  useQuickUIEventListener('enemySpawn', (event) => {
    console.log('Enemy spawned:', event.payload)
    // Update UI state here
  })

  // Listen for UE5 key navigation events (suitable for TV or gamepad remote control)
  useInputKeyEventListener({
    onKeyAction: (action) => {
      console.log('Key Navigation:', action)
    }
  })

  // Use optimized callback management
  useUECallback('OnPlayerDataUpdated', (data) => {
    console.log('Player data updated:', data)
    // Process player data update
  })

  // Use filterUECallBackJSonData for data filtering
  useUECallback(
    'OnPlayerDataUpdated', // Frontend callback function name
    (data) => {
      // Note: First check if returned data is JSON string, treat plain text as non-JSON
      if (typeof data === 'string') {
        try {
          data = JSON.parse(data)
        } catch {
          console.error('Invalid JSON string, treating as non-JSON:', data)
          return
        }
      }
    
      const filter = filterUECallBackJSonData(data, { health: (vs: any) => vs, isAlive: (vs: any) => vs })
      
      console.log('Filtered data:', filter)
    }
  )

  const handlePlayerAction = (action: string) => {
    triggerEvent({
      action,
      timestamp: Date.now(),
      playerId: 'player123'
    })

    sendPlayerEvent({
      actionType: action,
      player: 'player123'
    })
  }

  const handleGameStateChange = (state: string) => {
    sendGameEvent({
      newState: state,
      previousState: 'playing'
    })
  }

  return (
    <div className="game-ui">
      <div className="status-bar">
        <span>Status: {isConnected ? 'Connected' : 'Connecting...'}</span>
        <span>Last Key Action: {lastKeyAction || 'None'}</span>
        <button onClick={() => setUseMouse(!mouseEnabled)}>{mouseEnabled ? 'Disable' : 'Enable'} Mouse</button>
      </div>

      <div className="game-controls">
        <button onClick={() => handlePlayerAction('jump')}>Jump</button>
        <button onClick={() => handlePlayerAction('attack')}>Attack</button>
        <button onClick={() => handleGameStateChange('paused')}>Pause Game</button>
      </div>

      <div data-nohit className="no-mouse-zone">
        This area does not respond to mouse events
      </div>
    </div>
  )
}

export default function App() {
  return (
    <UEProvider>
      <GameUI />
    </UEProvider>
  )
}

#5. Type Definitions

#Type Definitions

// Key action type
type KeyAction = "Up" | "Down" | "Left" | "Right" | "Next" | "Previous" | "Select"

// Custom event interface
interface QuickEvent<Payload = QuickEventPayload> {
  type: 'event' // Event type (fixed as "event")
  topic: string // Event topic/name
  payload?: Payload // Event payload data
  timestamp: number // Event timestamp
  source: 'web' | 'ue' // Event source
}

type QuickEventPayload = Record<string, any> | null

#Using TypeScript Types

interface QuickEvent<Payload = QuickEventPayload> {
  type: 'event'
  topic: string
  payload?: Payload
  timestamp: number
  source: 'web' | 'ue'
}

type QuickEventPayload = Record<string, any> | null

#Using TypeScript Types

import { useQuickUIEvent, useQuickUIEventListener, type QuickEvent } from 'ue-connect'

// Define custom payload type
interface PlayerEvent {
  playerId: string
  health: number
  position: { x: number; y: number; z: number }
}

function TypedComponent() {
  const sendPlayerUpdate = useQuickUIEvent('playerUpdate')

  useQuickUIEventListener('playerUpdate', (event: QuickEvent<PlayerEvent>) => {
    if (event.payload) {
      console.log('Player ID:', event.payload.playerId)
      console.log('Player Health:', event.payload.health)
      console.log('Player Position:', event.payload.position)
    }
  })

  const updatePlayer = () => {
    sendPlayerUpdate({
      playerId: 'player123',
      health: 100,
      position: { x: 10, y: 20, z: 30 }
    })
  }

  return <button onClick={updatePlayer}>Update Player</button>
}

#6. Best Practices

  1. Performance Optimization
  • Use data-nohit attribute wisely to avoid unnecessary mouse event handling
  • Disable mouse events when not needed to reduce performance overhead
  1. Error Handling
  • Always check isConnected status before sending events
  • Add error handling and user feedback for critical operations
  1. Event Naming
  • Use clear event naming conventions
  • Keep event names consistent between Web and UE5 sides
  1. Data Format
  • Use consistent JSON data format
  • Avoid sending excessively large data packets
  1. Type Safety
  • Use TypeScript type definitions for custom event payloads
  • Leverage type checking to avoid runtime errors