IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity——观察者模式 -> 正文阅读

[游戏开发]Unity——观察者模式

观察者模式

一、Demo展示

2

二、设计思路

我们假设一种情况,在app中修改了头像,在所有显示头像的UI中都需要更改相应的图片,一个个去获取然后调用刷新会非常麻烦;

因此我们需要一个自动响应机制——观察者模式;

核心:一个key对应多个Action(委托);

流程:

1.提前在每个需要响应的UI中添加监听事件;

2.修改数据同时注册观察者,需要参数可传参;

3.每一帧在LateUpdate中调用响应函数,把所有添加了注册了事件执行一遍;

三、关键类

1.带参数委托

由于参数类型不确定,所以使用object类型;

public delegate void obsAct(object args);

2.ObserverMa(单例)

字段:

private Dictionary<string,  List<obsAct>> dicAll //存储所有事件和响应
private List<string> curAct = new List<string>();//存储当前帧注册的事件key值
private ArrayList objArgs = new ArrayList();	 //存储key对应的参数

方法:

1)添加监听

public void AddListener(string key, obsAct act)
{
    if (dicAll.ContainsKey(key))
    {
        dicAll[key].Add(act);
    }
    else
    {
        List<obsAct> actions = new List<obsAct>();
        actions.Add(act);
        dicAll.Add(key, actions);
    }
}

2)注册事件

public void Register(string key,object args = null)
{
    if (dicAll.ContainsKey(key))
    {
        curAct.Add(key);
        objArgs.Add(args);
    }
    else
    {
        Debug.Log("未注册观察事件");
    }
}

3)响应事件

public void Respond()
{
    for (int i = 0; i < curAct.Count; ++i)
    {
        List<obsAct> acts = dicAll[curAct[i]];
        for (int j = 0; j < acts.Count; ++j)
        {
            acts[j](objArgs[i]);
        }
    }

    curAct.Clear();
    objArgs.Clear();
}

四、测试类

这里为了方便,我只用了InputFiled和Text组件来完成;

InputFiled输入文字,结束时通知4个Text,Text显示输入的文字;

在Canvas上了脚本UIMa,UIMa的LateUpdate方法中调用了ObserverMa.I.Respond();

image-20210929173035588

完整代码:

1.InputFiled

public class InputStr : MonoBehaviour
{
    private InputField strInput;
    private string str = "";
    private bool isAdd = false;
    private void Start()
    {
        strInput = GetComponent<InputField>();
    }
    
    void Update()
    {
        if (strInput.isFocused && !isAdd)
        { 
            isAdd = true;
        }

        if (!strInput.isFocused && isAdd)
        {
            ObserverMa.I.Register(ObsStr.inputStr, strInput.text);
            isAdd = false;
        }
    }
}

2.Text

public class Text1 : MonoBehaviour
{
    public Text text;
    private void Start()
    {
        text = GetComponent<Text>();
        obsAct act = (str) => { text.text = str as string;};
        ObserverMa.I.AddListener(ObsStr.inputStr,act);
    }
}

五、优化方案

1.所有的key值可以自动使用const string 类替代,避免每次注册需要手动输入字符串,且容易出错;

2.无参委托和有参委托可以分开写,写两套重写的注册方法,数据也分开存储,减少Object = null的存储;

以上是我对观察者模式的理解,如果有更好的想法可以给我留言;

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-10-01 17:12:29  更:2021-10-01 17:14:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 2:38:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码