介绍
通过UE提供的反射,插件会根据配置生成指定模块和插件下的类,结构体,枚举,以及资源类型。
基础概念
UE和C#两侧的反射类型存在一一对应关系,对于简单类型比较容易理解,针对如UObject,蓝图等此类复杂类型,需要先了解一下UE中Package的概念,推荐UE4的资源管理和[中文直播]第33期 | UE4资产管理基础1 | Epic 大钊。
- C++
- Blueprint
如AActor,会将/Script/Engine.Actor映射为Script.Engine.Actor,规则为去掉首位/,并将/替换为.
如BP_TestReflectionPropertyActor_C,会将/Game/UnitTest/Reflection/BP_TestReflectionPropertyActor.BP_TestReflectionPropertyActor_C映射为Script.Game.UnitTest.Reflection.BP_TestReflectionPropertyActor_C,规则为加上Script/,去掉BP_TestReflectionPropertyActor.,并将/替换为.
数据类型
针对不同的数据类型,有不同的处理方式,分为以下几个大类。
- 基本类型
- 字符串
- 枚举
- 结构体
- UObject
- 模板
- 容器
- 代理
| C++ | C# |
|---|---|
| bool | bool |
| int8 | sbyte |
| int16 | short |
| int32 | int |
| int64 | long |
| uint8 | byte |
| uint16 | ushort |
| uint32 | uint |
| uint64 | ulong |
| float | float |
| double | double |
| C++ | C# |
|---|---|
| FName | Script.CoreUObject.FName |
| FText | Script.CoreUObject.FText |
| FString | Script.CoreUObject.FString |
对于枚举和TEnumAsByte都会被对应到映射关系下的枚举。示例:枚举
会生成反射变量,StaticStruct,构造函数和析构函数等。示例:结构体
会生成反射变量,反射函数,接口函数和StaticClass等。示例:UObject
| C++ | C# |
|---|---|
| TScriptInterface | Script.CoreUObject.TScriptInterface`1 |
| TSubclassOf | Script.CoreUObject.TSubclassOf`1 |
| TWeakObjectPtr | Script.CoreUObject.TWeakObjectPtr`1 |
| TLazyObjectPtr | Script.CoreUObject.TLazyObjectPtr`1 |
| TSoftObjectPtr | Script.CoreUObject.TSoftObjectPtr`1 |
| TSoftClassPtr | Script.CoreUObject.TSoftClassPtr`1 |
| TOptional | Script.CoreUObject.TOptional`1 |
| C++ | C# |
|---|---|
| TArray | Script.CoreUObject.TArray`1 |
| TSet | Script.CoreUObject.TSet`1 |
| TMap | Script.CoreUObject.TMap`2 |
单播和多播都会映射为C#中的类,并且提供相关操作函数。
- 单播
- 多播
示例:单播
- C++
- C#
DECLARE_DYNAMIC_DELEGATE_RetVal_TwoParams(FEventReply, FOnPointerEvent, FGeometry, MyGeometry, const FPointerEvent&, MouseEvent);
using System;
using Script.CoreUObject;
using Script.Library;
using Script.SlateCore;
using Script.UMG;
namespace Script.UMG.Widget
{
public class FOnPointerEvent : FDelegate<Func<FGeometry, FPointerEvent, FEventReply>>
{
public FOnPointerEvent() => FDelegateImplementation.FDelegate_RegisterImplementation(this);
~FOnPointerEvent() => FDelegateImplementation.FDelegate_UnRegisterImplementation(GarbageCollectionHandle);
public FEventReply Execute(FGeometry MyGeometry, FPointerEvent MouseEvent)
{
return FDelegateImplementation.FDelegate_Execute3Implementation(GarbageCollectionHandle, MyGeometry, MouseEvent) as FEventReply;
}
}
}
示例:多播
- C++
- C#
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnButtonClickedEvent);
using System;
using Script.CoreUObject;
using Script.Library;
namespace Script.UMG
{
public class FOnButtonClickedEvent : FMulticastDelegate<Action>
{
public FOnButtonClickedEvent() => FMulticastDelegateImplementation.FMulticastDelegate_RegisterImplementation(this);
~FOnButtonClickedEvent() => FMulticastDelegateImplementation.FMulticastDelegate_UnRegisterImplementation(GarbageCollectionHandle);
public void Broadcast()
{
FMulticastDelegateImplementation.FMulticastDelegate_Broadcast0Implementation(GarbageCollectionHandle);
}
}
}
变量访问
对于C++或者蓝图中的反射变量,会生成对应的Properties,而非Fields,实际内存还是放在C++侧。
示例:变量访问
- C++
- C#
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TestReflectionPropertyActor.generated.h"
UCLASS()
class UNREALCSHARPTEST_API ATestReflectionPropertyActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestReflectionPropertyActor();
public:
UPROPERTY(BlueprintReadWrite)
int32 Int32Value;
};
using Script.CoreUObject;
namespace Script.UnrealCSharpTest
{
public partial class UUnitTestSubsystem
{
private void TestReflectionProperty()
{
var PropertyActor = GetWorld().SpawnActor<ATestReflectionPropertyActor>(new FTransform());
var Int32Value = PropertyActor.Int32Value;
PropertyActor.Int32Value = 21;
}
}
}
函数调用
对于C++或者蓝图中的反射函数,会生成对应的C#函数,并且处理好函数默认参数。
示例:函数调用
- C++
- C#
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "TestReflectionFunctionActor.generated.h"
UCLASS()
class UNREALCSHARPTEST_API ATestReflectionFunctionActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ATestReflectionFunctionActor();
public:
UFUNCTION(BlueprintCallable)
void SetInt32ValueFunction(int32 InInt32Value);
UFUNCTION(BlueprintCallable)
int32 GetInt32ValueFunction() const;
UFUNCTION(BlueprintCallable)
void OutInt32ValueFunction(int32& OutInt32Value) const;
};
using Script.CoreUObject;
using Script.Engine;
namespace Script.UnrealCSharpTest
{
public partial class UUnitTestSubsystem
{
private void TestReflectionFunction()
{
var FunctionActor = GetWorld().SpawnActor<ATestReflectionFunctionActor>(new FTransform());
var Int32Value = FunctionActor.GetInt32ValueFunction();
FunctionActor.SetInt32ValueFunction(21);
var OutInt32Value = 12;
FunctionActor.OutInt32ValueFunction(ref OutInt32Value);
}
}
}