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

2.4 KiB
Raw Blame History

title, date, excerpt, tags, rating
title date excerpt tags rating
UE5 MVVM 笔记 2025-08-26 10:05:44

前言

Example

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