-
Notifications
You must be signed in to change notification settings - Fork 68
Code reflection
There may be times when you want to access a Blueprint (or C++) class at runtime which wouldn't have normally been accessible from C#. The UE4 reflection system makes this possible.
In the following example the short path of a Blueprint class is used to find the class, get a int32 property named TestValue
, and then set the value on all actors of that class type in the world.
[UFunction]
private void OnClick()
{
UClass unrealClass = UClass.GetClass("SomeBlueprintClass_C");
if (unrealClass != null)
{
UIntProperty intProperty = unrealClass.FindPropertyByName((FName)"TestValue") as UIntProperty;
if (intProperty != null)
{
AActor[] actors = UGameplayStatics.GetAllActorsOfClass(this, unrealClass);
foreach (AActor actor in actors)
{
int currentValue = intProperty.Accessor.GetValue(actor);
intProperty.Accessor.SetValue(actor, currentValue + 1);
}
}
}
}
It's also possible to dynamically invoke functions using UObject.DynamicInvoke
(by passing the function name) or UFunction.DynamicInvoke
. It should be noted that these kind of function calls are much more expensive than other kinds of function calls.
The following example calls the function TestFunc
defined in a Blueprint, where there is 1 input of type Integer
which is passed by reference. The modified value is then printed to the screen.
[UFunction]
private void OnClick()
{
UClass unrealClass = UClass.GetClass("SomeBlueprintClass_C");
if (unrealClass != null)
{
UFunction function = unrealClass.FindFunctionByName((FName)"TestFunc", false);
if (function != null)
{
AActor[] actors = UGameplayStatics.GetAllActorsOfClass(this, unrealClass);
foreach (AActor actor in actors)
{
object[] args = { 0 };
function.DynamicInvoke(actor, args);
PrintString("TestFunc: " + args[0], FLinearColor.Red);
}
}
}
}
This is similar to the first example. Here we have a Blueprint defined type and pass an instance of it in as a function parameter to a C# defined function.
We can't directly access the properties / functions defined in the Blueprint (as C# doesn't know about them). But you can use reflection to get this information if you really need to.
[UFunction, BlueprintCallable]
public void MyFunc(UObject obj)
{
UClass unrealClass = obj.GetClass();
if (unrealClass != null)
{
UIntProperty intProperty = unrealClass.FindPropertyByName((FName)"TestValue") as UIntProperty;
if (intProperty != null)
{
int currentValue = intProperty.Accessor.GetValue(obj);
intProperty.Accessor.SetValue(obj, currentValue + 1);
}
}
}