diff --git a/03-UnrealEngine/UI/UE5 MVVM 笔记.md b/03-UnrealEngine/UI/UE5 MVVM 笔记.md new file mode 100644 index 0000000..4ed3866 --- /dev/null +++ b/03-UnrealEngine/UI/UE5 MVVM 笔记.md @@ -0,0 +1,86 @@ +--- +title: UE5 MVVM 笔记 +date: 2025-08-26 10:05:44 +excerpt: +tags: +rating: ⭐ +--- +# 前言 +- 知乎文章 + - [UE5.6新功能MVVM使用方式(从笔记里迁移)](https://zhuanlan.zhihu.com/p/1918763422243325641) +- + +# Example +```c++ +UCLASS(Blueprintable) +class UMyViewModelBase : public UMVVMViewModelBase +{ + GENERATED_BODY() + +private: + // FieldNotify:使得属性可以用于通知广播 + // Setter:此属性可以被设置,Setter函数的名称格式 Set[Variable Name],CurrentHealth的Setter为:SetCurrentHealth + // Setter = [Function Name] 也可以自己指定名称,写法如前 + // Getter:此属性可以被获取,Getter函数的名称格式为 Get[Variable Name],CurrentHealth的Getter为:GetCurrentHealth + // Getter = [Function Name] 也可以自己指定名称,写法如前 + // 此字段在ViewModel中使用Get/Set访问,在蓝图中是Public的,在蓝图中ViewBanding使用Get/Set + UPROPERTY(BlueprintReadWrite, FieldNotify, Setter, Getter, meta=(AllowPrivateAccess)) + int32 CurrentHealth; + + UPROPERTY(BlueprintReadWrite, FieldNotify, Setter, Getter, meta=(AllowPrivateAccess)) + int32 MaxHealth; + +public: + void SetCurrentHealth(int32 NewCurrentHealth) + { + if (UE_MVVM_SET_PROPERTY_VALUE(CurrentHealth, NewCurrentHealth)) + { + UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED(GetHealthPercent); + } + } + + void SetMaxHealth(int32 NewMaxHealth) + { + // 内部是一个模版函数,有特化版本,最终作用是做compare并触发Boradcast + // 原理也一样,就是通过名字传递Property做compare, + // 然后通过名字拿到Fiedld取Delegate进行boradcast + // ([Variable Name][NewValue]) + if (UE_MVVM_SET_PROPERTY_VALUE(MaxHealth, NewMaxHealth)) + { + // 如果MaxHealth改变了,HealthPercent也需要更新 + // 内部通过名称拿到一个FieldId,然后通过FieldId找到对应的Delegate进行Boradcast + UE_MVVM_BROADCAST_FIELD_VALUE_CHANGED(GetHealthPercent); + } + + } + + int32 GetCurrentHealth() const + { + return CurrentHealth; + } + + int32 GetMaxHealth() const + { + return MaxHealth; + } + +public: + /** + * 必须具有带 FieldNotify 和 BlueprintPure 说明符的 UFUNCTION 宏。 + * 不得带有参数。 + * 必须是 const 函数。 + * 必须仅返回单个值(没有输出参数)。 + * @return + */ + UFUNCTION(BlueprintPure, FieldNotify) + float GetHealthPercent() const + { + if (MaxHealth != 0) + { + return (float) CurrentHealth / (float) MaxHealth; + } + else + return 0; + } +}; +``` \ No newline at end of file