vault backup: 2025-08-26 11:56:17
This commit is contained in:
@@ -8,6 +8,7 @@ rating: ⭐
|
||||
# 前言
|
||||
- 知乎文章
|
||||
- [UE5.6新功能MVVM使用方式(从笔记里迁移)](https://zhuanlan.zhihu.com/p/1918763422243325641)
|
||||
-
|
||||
-
|
||||
|
||||
# Example
|
||||
@@ -83,4 +84,84 @@ public:
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
```
|
||||
```
|
||||
|
||||
|
||||
# MVVM
|
||||
ViewModels管理器位于:Window -> ViewModels。
|
||||
|
||||
大致操作步骤:
|
||||
1. 在该界面中创建ViewModels。
|
||||
2. 选择ViewModels并且添加动态绑定的变量。
|
||||
3. 修改CreationType(有4种类型)。
|
||||
|
||||
## MVVM CreationType
|
||||
### Create Instance (一对一)
|
||||
自动为控件的每个唯一实例创建一个新的Viewmodel实例。这意味着,如果你在视口中有同一控件的数个副本,并且你更改了其中一个副本的Viewmodel变量,则只有该控件会更新,所有其他副本将保持不变。同理,如果你创建多个使用同一Viewmodel的不同控件,这些控件都不会感知到彼此信息的变化。
|
||||
|
||||
**UE只会在ViewModel为空时创建新实例,ViewModel会在PreConstruct和Construct事件之间创建。**
|
||||
|
||||
### Manual(看设计,可以一对多)
|
||||
自行创建ViewModel实例进行手动指定赋值,在赋值之前,Widget中的ViewModel一直都是空的。
|
||||
|
||||
### Global View Model Collection (全局共享)
|
||||
[MVVMGameSubsystem](https://zhida.zhihu.com/search?content_id=259254754&content_type=Article&match_order=1&q=MVVMGameSubsystem&zhida_source=entity)中维护了一个全局访问的ViewModel列表,可以通过任意GameInstance访问。
|
||||
|
||||
Note:这里注意,AddViewModel必须提供ContextName,UE要求此名称必须和ViewMode的类名一致。
|
||||
原因:MVVM中维护数据使用的是TArray,内存连续,可以通过索引快速查询。
|
||||
|
||||
数据结构:
|
||||
```text
|
||||
{
|
||||
// 类型
|
||||
TSubclassOf<UMVVMViewModelBase> ContextClass;
|
||||
// 上下文信息,UE要求和类名一致
|
||||
FName ContextName;
|
||||
}
|
||||
```
|
||||
|
||||
### Property Path
|
||||
类似如下写法:(加粗的self是默认的,不需要手动写,和函数默认的This类似)
|
||||
|
||||
**Self.**GetPlayerController.Vehicle.ViewModel
|
||||
|
||||
这个指定方式是说,通过当前的Widget获取PC,通过PC拿到载具上的ViewModel信息。
|
||||
|
||||
|
||||
## 使用方法
|
||||
1. 从MVVM界面中直接退拽进UMG编辑器。
|
||||
2. Detail面板Binding。
|
||||
3. 使用ViweBinding(Window→ViewBindings)
|
||||
|
||||
![[UMG_MVVM_ViewBindings.jpg|800]]绑定方向
|
||||
OneTimeToWidget(←1):VM到控件,执行一次。
|
||||
OneWayToWidget: VM到V,每次刷新都会通知
|
||||
OneWayToViewModel :V到VM, 每次通知到VM,典型案例:编辑文本或图形选项,按钮需要自己包裹一下(**研究下给个合理方式**)
|
||||
TwoWay:绑定在两个方向都可用,可以相互通知,不用担心陷入死循环,MVVMModelBase中的SetFunc,已经做好了处理,只有值不等才会Boradcast
|
||||
|
||||
### Conversion Function
|
||||
何时使用?
|
||||
如图:我想要在Text文本中显示我最大血量,最大血量是integer,如果直接绑定,compile时会有报错无法编译,此时就需要有转换函数出现了,通过转化函数将Integer转化为可用的FText
|
||||
![[UMG_MVVM_ViewBindings_ConversionFunction.jpg|800]]
|
||||
|
||||
如何自定义转化函数:
|
||||
如果我们是自己的某个接口,或者一个特殊的类型要有额外操作怎么处理,这个时候就需要自定义转化函数。
|
||||
新的转换函数可以全局添加或在UserWidget(控件蓝图)上添加。函数不能是事件或网络,也不能弃用或仅限编辑器。函数需要对蓝图可见,有一个输入参数和一个返回值。如果在全局定义,函数还需要带有static关键字。如果在UserWidget中定义,函数还需要带有pure和const关键字。
|
||||
一个在蓝图中转化的示例:
|
||||
![[UMG_MVVM_ViewBindings_ConversionFunction_Custom.jpg|800]]![[UMG_MVVM_ViewBindings_ConversionFunction_CustomFunction.jpg|800]]
|
||||
![[UMG_MVVM_ViewBindings_ConversionFunction_CustomFunction_Settings.jpg|800]]**Note:当前版本如果在Bindings赋值,然后再Deatails再次赋值,这样会出问题,绑定会失效,解决办法:从Bindings中删掉原来的绑定,重新赋值,(基于此原因,个人建议关掉DeatailsBind的入口)**
|
||||
|
||||
### 禁用旧版绑定
|
||||
旧版的Bind并不是监听事件,而是通过Tick刷新。
|
||||
新版确实是通过蓝图可用的多播委托去通知。
|
||||
为了防止两种方式混用(**我们也不允许使用旧版方式绑定,性能洼地**),需要禁用旧版绑定。
|
||||
|
||||
#### DiablePropertBinding
|
||||
![[UMG_DisablePropertBinding.jpg|800]]
|
||||
开启上选项后将禁用传统属性绑定到Widget的选项,可以看到如图效果,BindList中只有ViewModel选项。
|
||||
![[UMG_DisablePropertBinding_Result.jpg]]
|
||||
|
||||
#### ViewModel禁用DetailsBind
|
||||
![[UMG_MVVM_DisableDetailsBinding.jpg|800]]
|
||||
|
||||
![[UMG_MVVM_DisableDetailsBinding_Result.jpg]]
|
||||
|
Reference in New Issue
Block a user