UPROPERTY:一个宏管三件事

UPROPERTY 是 C++ 与蓝图之间最常用的桥梁。同一个宏照顾三件事:暴露(编辑器可见/蓝图可读写)、内存(垃圾回收)与网络(同步)。

UCLASS()
class AMyCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    // 蓝图可读可写,编辑器可编辑
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Combat")
    float MaxHealth = 100.f;

    // 蓝图只读(C++ 里修改,蓝图里显示)
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Combat")
    float CurrentHealth;

    // 蓝图可订阅的事件(第 3 章详讲)
    UPROPERTY(BlueprintAssignable, Category = "Combat")
    FOnHealthChanged OnHealthChanged;

    // 组件引用:蓝图可见但不可改
    UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Components")
    UStaticMeshComponent* WeaponMesh;
};

说明符速查

说明符 编辑器 蓝图 典型用途
EditAnywhere 全部实例可改 — 可调参数
EditDefaultsOnly 仅 CDO(类默认对象)可改 — 角色基础速度等"类级"参数
VisibleAnywhere 只读显示 — 运行时状态、组件指针
BlueprintReadWrite — 读 + 写 蓝图要修改的值
BlueprintReadOnly — 只读 C++ 维护、蓝图查询的值
BlueprintAssignable — 可绑定事件 委托(事件分发器)
EditDefaultsOnly, BlueprintReadOnly CDO 可改 + 蓝图只读 只读 给蓝图读但只在编辑器配的值

新手最常见的错误是 EditAnywhere 滥用:把只该在 CDO 上配的参数标成 EditAnywhere,导致每个关卡实例都改了自己的值,世界设置里一团乱麻。经验:"类级"参数一律 EditDefaultsOnly,只有真想每实例独立配的才 EditAnywhere。

Category:不只是分组

Category="Combat|Health" 这种斜杠写法能造出多级菜单。养成分类习惯有两个实际好处:一、蓝图节点里找函数快;二、UE 的"按分类过滤"和配置文件过滤(BlueprintConfiguration)都依赖它。一个 200 个属性的大类如果没有分类,使用者会疯。

meta:那些不出口但很有用的标签

UPROPERTY(EditAnywhere, meta=(ClampMin="0", ClampMax="500", ToolTip="最大生命值"))
float MaxHealth;
  • ClampMin/ClampMax:编辑器里限制范围,防止策划填出 99999;
  • ToolTip:鼠标悬停说明,蓝图里也看得到;
  • ExposeOnSpawn=true:生成时可在 "Spawn Actor" 节点里直接传参;
  • EditCondition="bEnabled":勾选后才可编辑的联动控件。

这些细节决定了非程序员用你的类时"顺不顺手"。

蓝图读写 C++ 变量的隐藏成本

BlueprintReadWrite 给了蓝图修改权,也意味着策划可能把数值改成任何值。如果你的 C++ 逻辑假设 MaxHealth >= 1,最好在 C++ 里做一次 Clamp,而不是相信蓝图的自觉性。同样的,BlueprintReadOnly 是推荐默认——只暴露需要暴露的写权限。

本章小结

  • UPROPERTY 一举三得:暴露、内存、网络。
  • 常用说明符组合:EditAnywhere+BlueprintReadWrite(可调可改)、VisibleAnywhere+BlueprintReadOnly(状态展示)、BlueprintAssignable(事件)。
  • 类级参数用 EditDefaultsOnly,别让每个实例都有自己的副本。
  • meta 标签(Clamp/ToolTip/EditCondition)是给非程序员的用户体验。