UnrealCLR not tied to how organized the development environment. Any IDE such as Visual Studio, Visual Code, or Rider, can be used to manage a project with C# code. A programmer has full freedom to set up the building pipeline in any desirable way just as for a regular .NET library.
After building and installing the plugin, use IDE or CLI tool to create a .NET class library project which targets .NET Core in any preferable location. Don't store source code in %Project%/Managed
folder of the engine's project, it's used exclusively for loading and packaging user assemblies by the plugin.
Add a reference to UnrealEngine.Framework.dll
assembly located in Source/Managed/Framework/bin/Release
folder. Create a new or open a C# class file in the .NET project and replace its content with the following code:
using System;
using System.Drawing;
using UnrealEngine.Framework;
namespace Game {
public static class Main { // Indicates the main entry point for automatic loading by the plugin
public static void OnBeginWorld() => Debug.AddOnScreenMessage(-1, 10.0f, Color.DeepPink, "Hello, Unreal Engine!");
public static void OnEndWorld() => Debug.AddOnScreenMessage(-1, 10.0f, Color.DeepPink, "See you soon, Unreal Engine!");
public static void OnPrePhysicsTickWorld(float deltaTime) => Debug.AddOnScreenMessage(1, 10.0f, Color.DeepPink, "On pre physics tick invoked!");
public static void OnDuringPhysicsTickWorld(float deltaTime) => Debug.AddOnScreenMessage(2, 10.0f, Color.DeepPink, "On during physics tick invoked!");
public static void OnPostPhysicsTickWorld(float deltaTime) => Debug.AddOnScreenMessage(3, 10.0f, Color.DeepPink, "On post physics tick invoked!");
public static void OnPostUpdateTickWorld(float deltaTime) => Debug.AddOnScreenMessage(4, 10.0f, Color.DeepPink, "On post update tick invoked!");
}
}
All functions of the main entry point are optional, and it's not necessary to implement them for every tick group.
Build a .NET assembly to %Project%/Managed
folder of the engine's project, and make sure that no other assemblies of other .NET projects are stored there.
Assemblies that no longer referenced and unused in the project will persist in %Project%/Managed
folder. Consider maintaining this folder through IDE or automation scripts.
Enter the play mode to execute managed code.
using System;
using System.Drawing;
using UnrealEngine.Framework;
namespace Game {
public static class System { // Custom class for loading functions from blueprints
public static void Function() => Debug.AddOnScreenMessage(-1, 10.0f, Color.DeepPink, "Blueprint function invoked!");
}
}
To run a blueprint function, create a new or open an existing level of the engine. Open level blueprint by navigating to Blueprints -> Open Level Blueprint
and create a basic execution flow:
Compile the blueprint and enter the play mode.
The plugin is transparently integrated into the packaging pipeline of the engine and ready for standalone distribution.
The plugin provides two blueprints to manage the execution. They can be used in any combinations with other nodes, data types, and C++ code to weave managed functionality with events. It's highly recommended to use creative approaches that extract information from blueprint classes instead of using plain strings for managed functions.
Find Managed Function
Attempts to find a managed function from loaded assemblies. This node performs a fast operation to retrieve function pointer from the cached dictionary once assemblies loaded after entering the play mode. Logs an error if the managed function was not found and sets Result
parameter to false
. Optional
checkbox indicates if the managed function is optional and the error should not be logged.
Execute Managed Function
Attempts to execute a managed function. This node performs a fast execution of a function pointer. Optionally allows passing an object reference of the engine to managed code with conversion to an appropriate type.
Two options are available to pass data between the managed runtime and the engine.
Blueprint variables
The engine provides a convenient way to manage variables/properties per actor/component basis that are accessible from the world outliner.
Instance-editable blueprint variables:
Exposed as properties and accessible from the world outliner:
See Actor, ActorComponent, and AnimationInstance classes for appropriate methods to get and set data.
Console variables
Data that should be globally accessible can be stored in console variables and modified from the editor's console.
See ConsoleVariable class for appropriate methods to get and set data.
The plugin is compatible with .NET tools and makes the engine's application instance visible as a regular .NET application for IDEs and external programs.