This project implements a remote control client for the Unreal Engine 4 editor (since 4.23).
It implements the remote control protocol client over HTTP with JSON of a running Unreal Editor instance, and allows external programs to interact with the Unreal Editor in real time, with a fully object-oriented interface emulating C++ code. It can be used from the browser or with Node, and is fully typed. Several engine blueprint libraries are also included.
Read what you can do with Web Remote Control and the installation instructions below to get started.
Important: The feature is currently in Beta in the engine, so it may require updating between different engine releases.
The client is written in TypeScript and provides an object interface emulating UE4's object intefaces, and some type definition for engine data structures.
You need a Node.js installation with npm.
git clone https://github.com/sovietspaceship/ue4-remote-control
cd ue4-remote-control
npm install
To build, run npm run compile
. This will compile all TypeScript files to ECMAScript 6
in dist/
, with typings included. This step is optional as compiled files are already provided
in the repository, but required if you make any changes.
To use in your library as a dependency, run
npm install https://github.com/sovietspaceship/ue4-remote-control
and then require or import it in one of the following ways:
import { UObject } from 'ue4-remote-control/dist/classes/uobject' // full access to all classes by path; dist is required for the time being
import { UObject } from 'ue4-remote-control' // this only exposes some core functionality exported by src/index.ts
const { AActor } = require('ue4-remote-control/dist/classes/actors/actor')
Classes can extend UObject to emulate their interface in the engine code. This is not necessary to interact with the engine, but ensures all requests are typechecked by TypeScript.
To create a new object type, extend UObject. See src/objects
for more examples.
Blueprint libraries are referenced by their default object, e.g. /Script/EditorScriptingUtilities.Default__EditorLevelLibrary
.
Classes can inherit from each other, e.g. AStaticMeshActor
can inherit from AActor
. The system
is designed to mimick regular engine code, with the caveat that objects are not serialised in request payloads,
but referenced by their path instead.
import { AActor } from 'ue4-remote-control/classes/actor'
type PetCatRequest = {
cat: ACat,
duration: number
}
export class AHuman extends AActor {
async petCat(cat: ACat, duration: number): Promise<boolean> {
const { returnValue } = await this.call('PetCat', { cat, duration } as PetCatRequest)
return returnValue as boolean
}
}
then, to use the new method
const human = new AHuman('/Game/CatGame:Level.Level:Human.CatPetter')
const cat = new ACat('/Game/CatGame:Level.Level:Cat.Nyasu')
const catIsHappy: boolean = await human.PetCat(cat, 15120)
If you create some useful engine object classes, please submit a merge request!
Several engine libraries are included. Check src/classes/libraries
to see available methods. Most of these have been generated with scripts/generate-methods-from-docs.js
so, while it tries to preserve
as much type information as possible, some signatures may not match. This also generates a lot of classes, structs and enums
with empty definitions, which will have to be implemented.
- Getting all actors in the currently open level:
import { EditorLevelLibrary } from './classes/libraries/editor-level-library'
const ell = new EditorLevelLibrary()
const actors = await ell.GetAllLevelActors()
/*
actors = [
'/Game/Project/Level.Level:PersistentLevel.Actor1',
'/Game/Project/Level.Level:PersistentLevel.Actor2'
]
*/
- Getting and setting actor location
const actor = new AActor('/Game/Project/Level.Level:PersistentLevel.Actor1')
const location = await actor.GetActorLocation()
// location = { X: 0, Y: 482, Z: 0 }
const result = await actor.SetActorLocation({ X: 420, Y: 90, Z: 123 })
/*
result = {
SweepHitResult: {
bBlockingHit: false,
bStartPenetrating: false,
FaceIndex: -1,
...
},
ReturnValue: true
}
*/
- Managing actor properties:
const actor = new AActor('/Game/Project/Level.Level:PersistentLevel.Actor1')
const properties = await actor.loadAll()
const property = await actor.get('propertyName')
await actor.set('propertyName', 100)
Properties are cached when first retrieved. To reload, call loadAll
or pass true
as second argument to get
.
If you don't need the whole object architecture, you can use makeRequest
, defined in src/index.ts
:
import { makeRequest } from 'eu4-remote-control'
// makeRequest(method: HttpMethodCalls, endpoint: string, body: Object)
const response = await makeRequest('put', '/remote/object/call', {
objectPath: "/Game/Project/Level.Level:PersistentLevel.Actor1",
functionName: "SetActorLocation",
parameters: {
NewLocation: { X: 10, Y: 20, Z: 40 },
},
})
The main goal is to implement the following libraries:
Additional libraries implemented:
Missing development:
- Add implementations for classes, structs and enums lacking a body.
- Type signatures for class properties.
Also, I created a separate project for functions that are not provided by the engine:
Since everyone updates the engine at different times, I may not notice if there are issues with specific versions, or the latest. Please let me know if there are any breaking changes to the remote control API by opening an issue, or creating a merge request if you want to contribute fixes or improvements!