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