UE5 UPROPERTY 与 UFUNCTION

UPROPERTY 与 UFUNCTION

UPROPERTY

​ UPROPERTY宏用来说明变量,其参数可以规定可以在什么时候编辑和可视,可规定元数据和修改种类,规定网络同步

常用属性说明符

1. 编辑器可见 / 可编辑
说明符 作用
EditAnywhere 在所有地方(蓝图、细节面板、实例)可编辑
EditDefaultsOnly 仅在蓝图类的默认值面板可编辑(实例不可改)
EditInstanceOnly 仅在蓝图实例的细节面板可编辑(蓝图类默认值不可改)
VisibleAnywhere 编辑器可见但不可编辑(所有地方)
VisibleDefaultsOnly 仅蓝图类默认值面板可见(不可编辑)
VisibleInstanceOnly 仅蓝图实例面板可见(不可编辑)
2. 蓝图访问控制
说明符 作用
BlueprintReadWrite 蓝图中可读可写
BlueprintReadOnly 蓝图中只读(C++ 可写)
BlueprintAssignable 仅用于委托(Delegate),蓝图中可绑定事件
3. 序列化与 GC
说明符 作用
SaveGame 变量会被包含在 SaveGame 存档中(游戏存档时序列化)
Transient 变量不序列化(临时变量,加载时不会恢复值)
NoClear 编辑器中不会被 “清空” 按钮重置(仅对对象引用有效)
4. 网络同步
说明符 作用
Replicated 变量在服务器和客户端之间同步
ReplicatedUsing 同步时触发指定函数(如ReplicatedUsing = OnRep_MyVar

使用示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
UCLASS() // 必须加UCLASS宏,否则UPROPERTY无效
class MYPROJECT_API AMyTestActor : public AActor
{
GENERATED_BODY() // 反射系统必需的宏

public:
// 构造函数
AMyTestActor();

// ========== 基础示例:编辑器可编辑 + 蓝图可读可写 ==========
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "基础参数")
int32 PlayerLevel = 1; // 默认值1

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "基础参数")
float MoveSpeed = 600.0f; // 移动速度

// ========== 只读示例:蓝图只读,编辑器可见 ==========
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "状态")
bool bIsAlive = true; // 存活状态

// ========== 存档示例:保存游戏时序列化 ==========
UPROPERTY(SaveGame, EditDefaultsOnly, Category = "存档")
FString PlayerName = TEXT("默认玩家"); // 玩家名称

// ========== 网络同步示例 ==========
UPROPERTY(ReplicatedUsing = OnRep_HPChanged, EditAnywhere, Category = "网络")
float CurrentHP = 100.0f; // 当前血量,同步时触发OnRep_HPChanged

// 同步回调函数(必须是UFUNCTION)
UFUNCTION()
void OnRep_HPChanged()
{
// 血量变化后的逻辑(比如更新UI)
UE_LOG(LogTemp, Warning, TEXT("血量同步:%f"), CurrentHP);
}

// 必须重写GetLifetimeReplicatedProps来注册同步变量
virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
};

UFUNCTION

​ UFUNCTION是 UE 反射系统对函数的封装,普通 C++ 成员函数加上这个宏后,会被引擎识别,可以规定获得和UE编辑器,蓝图,同步等交流的功能。

常用属性说明符

1. 蓝图交互(最常用)
说明符 作用
BlueprintCallable 函数可在蓝图中调用(C++ 定义,蓝图执行),参数 / 返回值支持 UE 类型
BlueprintImplementableEvent 函数仅在 C++ 声明,由蓝图实现(C++ 可调用,逻辑写在蓝图里)
BlueprintNativeEvent 函数有 C++ 默认实现,蓝图可重写(优先执行蓝图版本,也可调用 C++ 原版)
BlueprintPure 纯函数(无副作用,不修改成员变量),蓝图中可直接作为节点(无执行引脚)
BlueprintCosmetic 仅在客户端执行的装饰性函数(如 UI、特效,不影响游戏逻辑)
2. 网络 RPC(多人游戏)
说明符 作用
Server 客户端调用,服务器执行(需加_Validate验证函数)
Client 服务器调用,所有客户端执行(无验证)
NetMulticast 服务器调用,所有客户端 + 服务器执行(无验证)
WithValidation 配合Server使用,标记需要验证的 RPC 函数
3. 编辑器交互
说明符 作用
CallInEditor 编辑器细节面板中显示按钮,点击可直接调用该函数(无需运行游戏)
BlueprintCallable 函数可在蓝图中调用(C++ 定义,蓝图执行),参数 / 返回值支持 UE 类型
BlueprintPure 纯函数(无副作用,不修改成员变量),蓝图中可直接作为节点(无执行引脚)

使用示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
UCLASS()
class MYPROJECT_API AMyFunctionActor : public AActor
{
GENERATED_BODY()

public:
AMyFunctionActor();

// ========== 1. 蓝图可调用函数(基础) ==========
// 带参数+返回值,蓝图中显示为带执行引脚的节点
UPROPERTY(EditAnywhere, Category = "测试参数")
int32 BaseDamage = 10;

UFUNCTION(BlueprintCallable, Category = "战斗|伤害")
float CalculateFinalDamage(float Multiplier)
{
return BaseDamage * Multiplier; // 计算最终伤害
}

// ========== 2. 蓝图纯函数(无执行引脚) ==========
// 无副作用,仅返回值,蓝图中可直接嵌入其他节点
UFUNCTION(BlueprintPure, Category = "工具|判断")
bool IsPlayerFullHP(float CurrentHP, float MaxHP)
{
return CurrentHP >= MaxHP;
}

// ========== 3. 蓝图可实现事件(仅声明,蓝图写逻辑) ==========
// 无C++实现,必须在蓝图中重写
UFUNCTION(BlueprintImplementableEvent, Category = "事件")
void OnPlayerLevelUp(int32 NewLevel);

// ========== 4. 蓝图可重写事件(有C++默认实现) ==========
// 蓝图可重写,也可调用C++原版(Super::OnTakeDamage)
UFUNCTION(BlueprintNativeEvent, Category = "事件")
void OnTakeDamage(float DamageValue);
// 实现函数名必须加_Implementation
void OnTakeDamage_Implementation(float DamageValue)
{
UE_LOG(LogTemp, Warning, TEXT("C++默认伤害处理:受到%f伤害"), DamageValue);
}

// ========== 5. 编辑器可直接调用(CallInEditor) ==========
// 编辑器Details面板显示按钮,点击执行
UFUNCTION(CallInEditor, Category = "编辑器测试")
void PrintDebugInfo()
{
UE_LOG(LogTemp, Log, TEXT("编辑器调用:Actor名称=%s"), *GetName());
}

// ========== 6. 网络RPC示例(Server) ==========
// 客户端请求服务器执行伤害逻辑,需验证
UFUNCTION(Server, WithValidation, Reliable, Category = "网络")
void Server_ApplyDamage(float Damage);
bool Server_ApplyDamage_Validate(float Damage)
{
return Damage >= 0; // 验证:伤害值不能为负
}
void Server_ApplyDamage_Implementation(float Damage)
{
UE_LOG(LogTemp, Warning, TEXT("服务器执行:应用%f伤害"), Damage);
}
};