介绍
通过C#可以动态生成UClass,UInterface,UStruct和UEnum,并且不需要蓝图载体。
基础概念
在反射中,有介绍C++中Package和C#中Namespace的映射关系,对于动态类来说,namespace被限制为一定是Script.CoreUObject
,也就是说,动态类都会被创建到/Script/CoreUObject
中。这样做的目是有一些特殊的情景,如动态类被其他类所引用或者被放置在场景中时,但是由于没有蓝图载体,如果放在其他Package中,会导致序列化失败。其中UClassAttribute,UStructAttribute和UFunctionAttribute继承于OverrideAttribute,换言之,动态类的变量访问和函数调用又会回到反射绑定流程。同时,为了编辑器热重载,文件命名具有规范。
UEnum
如果需要标记BlueprintType,即被蓝图使用,需要将UnderlyingType设置为byte。枚举名和文件名都需要E
前缀。
示例:UEnum
- C#
using Script.Dynamic;
namespace Script.CoreUObject
{
[UEnum, BlueprintType]
public enum ETestDynamicEnum : byte
{
TestDynamicZero = 0,
TestDynamicOne = 1,
TestDynamicTwo = 2
}
}
UStruct
类名需要F
前缀,文件名不需要F
前缀。
示例:UStruct
- C#
using Script.Dynamic;
namespace Script.CoreUObject
{
[UStruct, BlueprintType]
public partial class FTestDynamicStruct
{
[UProperty, BlueprintReadWrite]
public int Value { get; set; }
}
}
UClass
约定了命令规范,对于动态蓝图类,需要以_C
结尾。类名需要U
或者A
前缀,文件名不需要U
或者A
前缀。
示例:UClass
- C#
using Script.Dynamic;
using Script.Engine;
namespace Script.CoreUObject
{
[UClass]
public partial class ATestRawDynamicFunctionActor : AActor, ITestDynamicInterface
{
public ATestRawDynamicFunctionActor()
{
Int32Value = 12;
}
[UProperty]
public int Int32Value { get; set; }
[UFunction]
public void SetInt32ValueFunction(int InInt32Value)
{
Int32Value = InInt32Value;
}
[UFunction]
public int GetInt32ValueFunction()
{
return Int32Value;
}
[UFunction]
public void OutInt32ValueFunction(ref int OutInt32Value)
{
OutInt32Value = Int32Value;
}
}
}
UInterface
不支持继承蓝图接口。接口名需要I
前缀,文件名不需要I
前缀。
示例:UInterface
- C#
using Script.Dynamic;
namespace Script.CoreUObject
{
[UInterface, Blueprintable]
public interface ITestDynamicInterface : IInterface
{
}
}
变量
同反射中,动态类的变量也是Properties,而非Fields。
示例:变量
- C#
[UProperty]
public int Int32Value { get; set; }
函数
对于引用类 型,只有ref参数,没有out参数。如果函数还会被其他蓝图调用,需要同时标记BlueprintCallable和BlueprintImplementableEvent。
示例:函数
- C#
[UFunction, BlueprintCallable, BlueprintImplementableEvent]
public void SetInt32ValueFunction(int InInt32Value)
{
Int32Value = InInt32Value;
}
[UFunction, BlueprintCallable, BlueprintImplementableEvent]
public int GetInt32ValueFunction()
{
return Int32Value;
}
[UFunction, BlueprintCallable, BlueprintImplementableEvent]
public void OutInt32ValueFunction(ref int OutInt32Value)
{
OutInt32Value = Int32Value;
}