Unity MVVM UniTask + 轻量级 ReactiveProperty

1. 负责数据绑定的"轻量级 ReactiveProperty"
cs 复制代码
using System;

// 极其轻量、0 GC 负担的响应式属性(示意版)
public class ReactiveProperty<T>
{
    private T _value;
    private Action<T> _onValueChanged;

    public T Value
    {
        get => _value;
        set
        {
            // 如果值没变,就不触发事件(防抖)
            if (Object.Equals(_value, value)) return; 
            _value = value;
            _onValueChanged?.Invoke(_value); // 通知所有订阅者
        }
    }

    public ReactiveProperty(T initialValue = default)
    {
        _value = initialValue;
    }

    // 提供给 UI 绑定的方法,返回一个可解绑的 Action
    public IDisposable Subscribe(Action<T> action)
    {
        _onValueChanged += action;
        action?.Invoke(_value); // 订阅时立刻推送一次当前值,让 UI 初始化
        return new Unsubscriber(() => _onValueChanged -= action);
    }
    
    // 内部类用于优雅解绑
    private class Unsubscriber : IDisposable
    {
        private Action _unsubscribe;
        public Unsubscriber(Action unsubscribe) => _unsubscribe = unsubscribe;
        public void Dispose() => _unsubscribe?.Invoke();
    }
}
Step 1: 编写 ViewModel(数据与逻辑中心)

这里包含了轻量级的状态数据,以及使用 UniTask 编写的线性业务流程。

cs 复制代码
using Cysharp.Threading.Tasks;
using UnityEngine;
using System.Threading;

public class ChestViewModel
{
    // 💡 纯粹的数据流:只负责保存状态,并在改变时向外广播
    public ReactiveProperty<string> ChestStateText { get; } = new ReactiveProperty<string>("点击开启宝箱");
    public ReactiveProperty<bool> IsButtonInteractable { get; } = new ReactiveProperty<bool>(true);

    // 💡 纯粹的控制流:使用 UniTask 串联整个异步逻辑
    // 传入 CancellationToken 是为了防止玩家在开箱中途关掉界面导致的空引用报错
    public async UniTask OpenChestAsync(CancellationToken token)
    {
        // 1. 改变状态:锁定按钮,更新文本
        IsButtonInteractable.Value = false;
        ChestStateText.Value = "宝箱正在开启中...";

        try
        {
            // 2. 等待宝箱抖动动画(等待 1 秒)
            // 魔法:Delay 不会产生任何 GC,且受 Unity TimeScale 影响
            await UniTask.Delay(1000, cancellationToken: token);

            // 3. 模拟网络请求战利品(等待 0.5 秒)
            ChestStateText.Value = "正在连接服务器...";
            await UniTask.Delay(500, cancellationToken: token); 
            string loot = "SSR 传说级大剑!🗡️"; // 假设这是网络返回的数据

            // 4. 最终展示结果
            ChestStateText.Value = $"开启成功!获得:{loot}";
        }
        catch (OperationCanceledException)
        {
            // 玩家中途关闭了界面,任务被优雅取消,不会有任何报错!
            Debug.Log("开箱流程被中断。");
        }
        finally
        {
            // 无论成功还是被取消,最终都可以执行清理逻辑
            IsButtonInteractable.Value = true;
        }
    }
}
Step 2: 编写 View(视图表现层)

UI 脚本现在变得 极其清爽 ,它只做两件事:把数据绑定到 UI 组件上,以及把用户的点击事件转发给 ViewModel。

cs 复制代码
using UnityEngine;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;
using System.Threading;

public class ChestView : MonoBehaviour
{
    public Text stateText;
    public Button openButton;

    private ChestViewModel _viewModel;
    private CancellationTokenSource _cts;

    void Start()
    {
        _viewModel = new ChestViewModel();
        _cts = new CancellationTokenSource(); // 用于管理异步任务的生命周期

        // 🌟 1. UI 数据绑定:将 ViewModel 的数据连接到 UI 元素
        _viewModel.ChestStateText.Subscribe(text => stateText.text = text);
        _viewModel.IsButtonInteractable.Subscribe(interactable => openButton.interactable = interactable);

        // 🌟 2. 事件转发:按钮点击触发 ViewModel 的异步流程
        openButton.onClick.AddListener(() =>
        {
            // Fire and Forget (触发并忘记),启动异步任务
            _viewModel.OpenChestAsync(this.GetCancellationTokenOnDestroy()).Forget();
        });
    }

    void OnDestroy()
    {
        // View 销毁时,取消所有正在进行的异步任务,防止内存泄漏或空引用!
        _cts.Cancel();
        _cts.Dispose();
    }
}
相关推荐
zcc8580797623 小时前
Unity 自动生成UI绑定+MVVM 架构模板
unity
LF男男4 小时前
MK - Grand Mahjong Game-
unity·c#
呆呆敲代码的小Y4 小时前
【Unity实战篇】| YooAsset + UOS CDN 云服务资源部署,实现正式热更流程
人工智能·游戏·unity·游戏引擎·免费游戏
WarPigs5 小时前
unity多语言框架
unity
RReality5 小时前
【UGUI】自定义 ListView 架构:设计、原理与可扩展性
unity·架构
棪燊15 小时前
Unity的Game视图在Scale放大后无法拖动
unity·游戏引擎
weixin_4239950017 小时前
unity 团结开发小游戏,加载AssetBundles
unity·游戏引擎
cyr___18 小时前
Unity教程(二十七)技能系统 黑洞技能(下)黑洞状态
学习·游戏·unity·游戏引擎
张老师带你学19 小时前
Unity 科幻武器系列
科技·游戏·unity·模型·游戏美术