Files
BlueRoseNote/03-UnrealEngine/UI/UE5 MVVM 笔记.md

86 lines
2.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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;
}
};
```