Unity自我实现响应式属性

        其实只是写着玩,响应式编程建议使用UniRx插件(一套成熟的响应式编程解决方案),我写的主要是借鉴一下这个思想,实现的也不够优雅,不过逻辑也算严密可以正常使用.你可以查看我写的理解响应式属性的思想.

        借鉴UniRx的ReactiveProperty类,且UniRx不仅有响应式属性.

using System;
using System.Linq;/// <summary>
/// 当值发生变化时触发回调(例如当玩家血量变化时更新GUI)。
/// </summary>
public class ReactiveValue<T>
{/// <summary>/// 定义过滤器委托,允许在设置新值时对值进行过滤或修正。/// </summary>private delegate T Filter(T originalValue, T newValue);/// <summary>/// 值变化时的回调委托。/// </summary>private Action<T> m_Set;/// <summary>/// 用于处理值变化前的过滤器。/// </summary>private Filter m_Filter;/// <summary>/// 当前的值。/// </summary>private T m_CurrentValue;/// <summary>/// 上一次的值,仅供内部使用。/// </summary>private T m_LastValue;/// <summary>/// 初始化值。/// </summary>/// <param name="initialValue">初始值。</param>public ReactiveValue(T initialValue){m_CurrentValue = initialValue;m_LastValue = m_CurrentValue;}/// <summary>/// 使用T的默认值初始化值/// </summary>public ReactiveValue() : this(default(T)) { }/// <summary>/// 判断当前值是否等于指定值。/// </summary>/// <param name="value">要比较的值。</param>/// <returns>如果当前值等于指定值,返回 true;否则返回 false。</returns>public bool IsEquals(T value){return m_CurrentValue != null && m_CurrentValue.Equals(value);}/// <summary>/// 添加一个回调/// </summary>/// <param name="callback">回调</param>/// <param name="immediateCall">添加了回调是否立即调用</param>public void AddChangeListener(Action<T> callback, bool immediateCall = false){if (m_Set == null || !m_Set.GetInvocationList().Contains(callback)){m_Set += callback;if (immediateCall){callback?.Invoke(m_CurrentValue);}}}/// <summary>/// 移除指定的监听器。/// </summary>/// <param name="callback">要移除的回调函数。</param>public void RemoveChangeListener(Action<T> callback){if (m_Set != null && m_Set.GetInvocationList().Contains(callback)){m_Set -= callback;}}/// <summary>/// 移除所有的监听器,谨慎使用,因为别人也进行了订阅/// </summary>public void RemoveAllChangeListeners(){m_Set = null;}/// <summary>/// 设置过滤器,过滤器将在回调前被调用,适合用于值限制(如玩家血量不能超过最大值等)。/// </summary>/// <param name="filter">过滤器委托:<原值,新值,返回值>。</param>public void SetFilter(Func<T, T, T> filter){m_Filter = new Filter(filter);}/// <summary>/// 获取当前值。/// </summary>/// <returns>返回当前值。</returns>public T Get(){return m_CurrentValue;}/// <summary>/// 设置新值,只有当新值与旧值不相同时才会触发回调。/// </summary>/// <param name="value">要设置的新值。</param>public void Set(T value){m_LastValue = m_CurrentValue;m_CurrentValue = value;if (m_Filter != null)m_CurrentValue = m_Filter(m_LastValue, m_CurrentValue);// 当新值和旧值不相等时触发回调if (m_LastValue == null || !m_LastValue.Equals(m_CurrentValue))m_Set?.Invoke(m_CurrentValue);}/// <summary>/// 强制更新值并触发回调,即使新值与旧值相同。/// </summary>/// <param name="value">要设置的新值。</param>public void SetValueForceCallBack(T value){m_LastValue = m_CurrentValue;m_CurrentValue = value;if (m_Filter != null)m_CurrentValue = m_Filter(m_LastValue, m_CurrentValue);// 强制触发回调m_Set?.Invoke(m_CurrentValue);}/// <summary>/// 设置新值但不触发回调。/// </summary>/// <param name="value">要设置的新值。</param>public void SetValueDontCallBack(T value){m_LastValue = m_CurrentValue;m_CurrentValue = value;if (m_Filter != null)m_CurrentValue = m_Filter(m_LastValue, m_CurrentValue);}
}

示例用法

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;public class Test : MonoBehaviour
{public Text textComponent;//一般会声明在数据层,可以优雅地实现MVC等框架,这里为了方便ReactiveValue<string> t = new ReactiveValue<string>("张三");void Start(){t.AddChangeListener(Handle, true);}// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.A)){if (t.IsEquals("张三")){t.Set("李四");}else{t.Set("张三");}}}void Handle(string t){textComponent.text = t;}private void OnDestroy(){t.RemoveChangeListener(Handle);}
}

UniRx实现

如果使用UniRx实现的话非常优雅.

AddTo的意思就是绑定了这个gameObject对象,当这个对象被销毁那么自动移除这个对象绑定的回调,就不需要傻傻的在OnDestroy中移除了,并且也可以使用匿名函数.

using System.Collections;
using System.Collections.Generic;
using UniRx;
using UnityEngine;
using UnityEngine.UI;public class Test : MonoBehaviour
{public Text textComponent;ReactiveProperty<string> t = new ReactiveProperty<string>("张三");void Start(){t.Subscribe(t => textComponent.text = t).AddTo(gameObject);}// Update is called once per framevoid Update(){if (Input.GetKeyDown(KeyCode.A)){if (t.Value == "张三"){t.Value = "李四";}else{t.Value = "张三";}}}}

实际是动态为gameObject对象动态添加了一个

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1540977.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

CertiK协助修复Solana大整数模幂运算中的DOS漏洞

导读&#xff1a; 本文深入探讨了区块链交易费⽤模型的重要性及其在确保网络安全和有效运行中的关键作用。通过对以太坊和Solana区块链网络的交易费⽤模型进行比较分析&#xff0c;揭示了不安全的交易计费可能引发的网络安全风险。特别关注了CertiK团队发现并协助修复的Solana…

【学术会议征稿】第四届计算机、信息工程与电子材料国际学术会议 (CTIEEM 2024)

第四届计算机、信息工程与电子材料国际学术会议 (CTIEEM 2024) The 4th International Conference on Computer Technology, Information Engineering and Electron Materials 随着信息技术的迅猛发展&#xff0c;计算机技术、信息工程以及电子材料领域的研究与创新成为推动现…

光伏设计软件的基本功能

一、屋顶绘制 光伏设计软件的首要功能是屋顶绘制。通过直观易用的界面&#xff0c;可以轻松绘制出建筑物的屋顶轮廓、结构细节等基本信息。软件支持多种屋顶类型的绘制&#xff0c;并允许用户自定义屋顶尺寸和形状。 二、参照物、障碍物放置 在光伏系统设计中&#xff0c;参照…

linux如何对c++进行内存分析

linux如何对c进行内存分析 背景分析方法以及原理原理分析结果以及重点关注 背景 在工作中&#xff0c;我遇到一个问题&#xff0c;需要将c写的进程部署到MCU上。由于MCU上可用的RAM 非常有限&#xff0c;所以在部署时就需要考虑到使用内存大小。所以为了搞清楚&#xff0c;内存…

go注册中心Eureka,注册到线上和线下,都可以访问

go注册中心Eureka&#xff0c;注册到线上和线下&#xff0c;都可以访问 本地通过127访问&#xff0c; 线上通过内网ip访问 package mainimport ("github.com/SimonWang00/goeureka""github.com/gin-gonic/gin""wbGo/controller""wbGo/task…

论文阅读 - MDFEND: Multi-domain Fake News Detection

https://arxiv.org/pdf/2201.00987 目录 ABSTRACT INTRODUCTION 2 RELATED WORK 3 WEIBO21: A NEW DATASET FOR MFND 3.1 Data Collection 3.2 Domain Annotation 4 MDFEND: MULTI-DOMAIN FAKE NEWS DETECTION MODEL 4.1 Representation Extraction 4.2 Domain Gate 4.…

机房动力环境监控系统组成

机房动力环境监控系统已经广泛应用于各种类型的机房,尤其稍微重要的机房,都需要做环境监控系统,因此我们要熟知这个系统,如果你还不懂的话,可以看看这篇文章。 一、动环系统简介 计算机系统数量与日俱增,其配套的环境设备也日益增多,计算机房已成为各大单位的重要组成…

线性规划中可行域为什么一定是凸的--证明

线性规划中的凸性证明 线性规划中可行域是凸的&#xff0c;这是自然能够想到和容易理解的道理。直观上&#xff0c;线性约束定义的可行域是由半平面的交集构成的&#xff0c;这些半平面的交集总是形成凸区域。 这么一个自然想到、容易理解的道理&#xff0c;怎么从数学上完备…

计算机毕业论文题目:设计与实现一个校园通知信息系统

设计与实现一个校园通知信息系统是一个涉及多个方面的复杂项目&#xff0c;它旨在提高信息传递的效率和准确性&#xff0c;确保学生、教师以及学校管理人员能够及时获取到重要的通知信息。以下是关于如何设计并实现这样一个系统的详细说明&#xff1a; 1. 需求分析 用户…

在Spring项目中,两个实用的工具(生成类与映射文件、API自动生成)

尊贵的Spring玩家&#xff0c;是不允许动脑思考的&#xff0c;所以我们要学会复制粘贴 1.生成类与映射文件 背景&#xff1a;在项目编写初期&#xff0c;我们已经设计好了表&#xff0c;后面就需要根据表来撰写实体类(model)和对应的sql语句(dao和mapper)。如果一个项目中&…

可视化数据分析收集软件Splunk Enterprise for Mac

Splunk Enterprise for mac 是一款强大的机器数据平台软件&#xff0c;具有以下特点和优势&#xff1a; 软件下载地址 一、功能强大的数据处理能力 专为收集、整理、搜索、分析和监控各种类型或来源的机器数据而设计&#xff0c;能够实时处理大量的机器生成数据&#xff0c;…

【PyTorch】张量操作与线性回归

张量的操作 Tensor Operation 拼接与切分 1.1 torch.cat() torch.cat(tensors, dim0, outNone)功能&#xff1a;将张量按维度dim进行拼接 tensors&#xff1a;张量序列dim&#xff1a;要拼接的维度 1.2 torch.stacok() torch.stack(tensors, dim0, outNone)功能&#xf…

java自定义线程池详解

目录 线程池使用线程池的目的线程池工作原理线程池常用方法自定义线程池等待队列拒绝策略线程工厂 线程池 使用线程池的目的 资源复用&#xff0c;降低开销。重复利用已创建的线程&#xff0c;避免线程频繁地创建和销毁带来的性能开销。方便线程的可管理性。线程是稀缺资源&a…

C++速通LeetCode中等第14题-旋转图像

思路图解&#xff1a; class Solution { public:void rotate(vector<vector<int>>& matrix) {// 设矩阵行列数为 nint n matrix.size();// 起始点范围为 0 < i < n / 2 , 0 < j < (n 1) / 2// 其中 / 为整数除法for (int i 0; i < n / 2; i)…

传知代码-多示例AI模型实现病理图像分类

代码以及视频讲解 本文所涉及所有资源均在传知代码平台可获取 概述 本文将基于多示例深度学习EPLA模型实现对乳腺癌数据集BreaKHis_v1的分类。EPLA模型是处理组织病理学图像的经典之作。EPLA模型是基于多示例学习来进行了&#xff0c;那么多示例学习模型对处理病理学图像具有…

滚动条指定距离滚动

/*** scroller 滚动条元素* to 滚动到位置* duration 滚动时间*/ function scrollLeftTo (scroller, to, duration) {let rafIdlet count 0const from scroller.scrollLeftconst frames duration 0 ? 1 : Math.round((duration * 1000) / 16)function cancel () {cancelAn…

中间件知识点-消息中间件(Kafka)二

Kafka 一、Kafka介绍及基本原理 kafka是一个分布式的、支持分区的、多副本、基于zookeeper的分布式消息系统/中间件。 kafka一般不会删除消息&#xff0c;不管这些消息有没有被消费。只会根据配置的日志保留时间(log.retention.hours)确认消息多久被删除&#xff0c;默认保留…

Navicat数据库管理工具实现Excel、CSV文件导入到MySQL数据库

1.所需要的工具和环境 navicat等第三方数据库管理工具云服务器中安装了 1Panel面板搭建的mysql数据库 2.基于 1Panel启动mysql容器 2.1 环境要求 安装前请确保您的系统符合安装条件&#xff1a; 操作系统&#xff1a;支持主流 Linux 发行版本&#xff08;基于 Debian / Re…

【Python机器学习】NLP信息提取——提取人物/事物关系

目录 词性标注 实体名称标准化 实体关系标准化和提取 单词模式 文本分割 断句 断句的方式 使用正则表达式进行断句 词性标注 词性&#xff08;POS&#xff09;标注可以使用语言模型来完成&#xff0c;这个语言模型包含词及其所有可能词性组成的字典。然后&#xff0c;该…

Jboss Administration Console弱⼝令

漏洞描述 Administration Console管理⻚⾯存在弱⼝令&#xff0c;admin:admin&#xff0c;登陆后台上传war包 , getshell 影响版本 全版本 环境搭建 因为这⾥⽤的环境是CVE-2017-12149的靶机 cd vulhub-master/jboss/CVE-2017-12149 docker-compose up -d 密码⽂件 /j…