首页 > 其他分享 >Unity___QFramework笔记

Unity___QFramework笔记

时间:2023-04-23 16:23:17浏览次数:39  
标签:Log void QFramework class Unity Debug new ___ public

引入Event

引入事件监听。

使用方法

  1. 先定义一个事件类
    // 定义数据变更事件
    public struct CountChangeEvent // ++
    {
        
    }
//执行事件
    this.SendEvent<CountChangeEvent>(); // ++
//注册事件
            this.RegisterEvent<CountChangeEvent>(e =>
            {
                UpdateView();

            }).UnRegisterWhenGameObjectDestroyed(gameObject);

引入Utility

实现存储功能,当存储数据非常多时,或者想换一种存储方式时,例如:EasySave/SQLite

使用方法

定义一个专门存储数据的类

   public class Storage : IStorage
    {
        public void SaveInt(string key, int value)
        {
            PlayerPrefs.SetInt(key,value);
        }

        public int LoadInt(string key, int defaultValue = 0)
        {
            return PlayerPrefs.GetInt(key, defaultValue);
        }
    }

然后在架构类中注册一下对象

     this.RegisterUtility<IStorage>(new Storage());

引入System

当需要进行分数统计或者成就统计等业务逻辑时,可以引入System对象
类似于注册一个事件去监听分数的变化执行相应的动作

public class AchievementSystem : AbstractSystem ,IAchievementSystem
    {
        protected override void OnInit()
        {
            this.GetModel<ICounterAppModel>() // -+
                .Count
                .Register(newCount =>
                {
                    if (newCount == 10)
                    {
                        Debug.Log("触发 点击达人 成就");
                    }
                    else if (newCount == 20)
                    {
                        Debug.Log("触发 点击专家 成就");
                    }
                    else if (newCount == -10)
                    {
                        Debug.Log("触发 点击菜鸟 成就");
                    }
                });
        }
    }

使用 BindableProperty 优化事件

数据+数据变更事件的对象,单类型需要被监听修改事件时,可以简化代码。

var age = new BindableProperty<int>(10);
age.Register(newAge=>{
  
  Debug.Log(newAge)
}).UnRegisterWhenGameObjectDestoryed(gameObject);
age++;
age--;
// 输出结果
// 11
// 10

当值发生改变时,制动调用事件
初始化事件api:RegisterWithInitValue

用接口设计模块(依赖倒置原则)

面向接口编程
承接上文,当我们需要换一种存储方式时,不需要将所有代码修改。
而是再创建一个IStorage的扩展类,例如EasySaveStorage,重写一下存储和加载方法
届时只需要改动一小块代码即可。

       // 注册存储工具对象
            // this.RegisterUtility<IStorage>(new Storage());
            this.RegisterUtility<IStorage>(new EasySaveStorage());

这样子就切换存储了

Query介绍

CQRS: Command Query Responsibility Saperation (读写分离原则)

查询方法

先定义一个查询类,并且继承相应的接口,

        public class SchoolAllPersonCountQuery : AbstractQuery<int>
        {
            protected override int OnDo()
            {
                return this.GetModel<StudentModel>().StudentNames.Count +
                       this.GetModel<TeacherModel>().TeacherNames.Count;
            }
        }
//查询方法
            if (GUILayout.Button("查询学校总人数"))
            {
                mAllPersonCount = this.SendQuery(new SchoolAllPersonCountQuery());
            }


架构规范与推荐用法

光速实现 EditorCounterApp 和 给主程看的开发模式

介绍了实现加减app的另一种方式。

基于这种框架的实现方法,可以实现底层三层的重用

Architecture 的好处

将所有的模块都注册进Architecture可以方便统一管理。

Command 拦截

在 Architecture 中覆写 ExecuteCommand ,可以实现一个Command日志。

        protected override void ExecuteCommand(ICommand command)
        {
            Debug.Log("Before " + command.GetType().Name + "Execute");
            base.ExecuteCommand(command);
            Debug.Log("After " + command.GetType().Name + "Execute");
        }

内置工具:TypeEventSystem

强大的事件系统

using UnityEngine;

namespace QFramework.Example
{
    public class TypeEventSystemBasicExample : MonoBehaviour
    {
        public struct TestEventA
        {
            public int Age;
        }

        private void Start()
        {
            TypeEventSystem.Global.Register<TestEventA>(e =>
            {
                Debug.Log(e.Age);
            }).UnRegisterWhenGameObjectDestroyed(gameObject);
        }
        
        private void Update()
        {
            // 鼠标左键点击
            if (Input.GetMouseButtonDown(0))
            {
                TypeEventSystem.Global.Send(new TestEventA()
                {
                    Age = 18
                });
            }

            // 鼠标右键点击
            if (Input.GetMouseButtonDown(1))
            {
                TypeEventSystem.Global.Send<TestEventA>();
            }
        }
    }
}

// 输出结果
// 点击鼠标左键,则输出:
// 18
// 点击鼠标右键,则输出:
// 0

支持继承

          TypeEventSystem.Global.Send<IEventA>(new EventB());

手动注销

TypeEventSystem.Global.UnRegister(OnEventA);

接口事件

类中需要继承:IOnEvent<接口名>
实现相应的方法。

非 MonoBehavior 脚本如何自动销毁

利用list数组存储将事件全部销毁。

public class NoneMonoScript : IUnRegisterList
{
    public List<IUnRegister> UnregisterList { get; } = new List<IUnRegister>();


    void Start()
    {
        TypeEventSystem.Global.Register<EasyEventExample.EventA>(a =>
        {
                    
        }).AddToUnregisterList(this);
    }

    void OnDestroy()
    {
        this.UnRegisterAll();
    }
}

内置工具:EasyEvent

可以脱离架构使用的工具,最多支持3种泛型,有着自动注销的优势。

基本用法

using UnityEngine;

namespace QFramework.Example
{
    public class EasyEventExample : MonoBehaviour
    {
        private EasyEvent mOnMouseLeftClickEvent = new EasyEvent();
        
        private EasyEvent<int> mOnValueChanged = new EasyEvent<int>();
        
        public class EventA : EasyEvent<int,int> { }

        private EventA mEventA = new EventA();

        private void Start()
        {
            mOnMouseLeftClickEvent.Register(() =>
            {
                Debug.Log("鼠标左键点击");
            }).UnRegisterWhenGameObjectDestroyed(gameObject);

            mOnValueChanged.Register(value =>
            {

                Debug.Log($"值变更:{value}");
            }).UnRegisterWhenGameObjectDestroyed(gameObject);


            mEventA.Register((a, b) =>
            {
                Debug.Log($"自定义事件:{a} {b}");
            }).UnRegisterWhenGameObjectDestroyed(gameObject);
        }

        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                mOnMouseLeftClickEvent.Trigger();
            }
            
            if (Input.GetMouseButtonDown(1))
            {
                mOnValueChanged.Trigger(10);
            }

            // 鼠标中键
            if (Input.GetMouseButtonDown(2))
            {
                mEventA.Trigger(1,2);
            }
        }
    }
}

// 输出结果:
// 按鼠标左键时,输出:
// 鼠标左键点击
// 按鼠标右键时,输出:
// 值变更:10
// 按鼠标中键时,输出:
// 自定义事件:1 2

内置工具:IOCContainer

框架中的注册和获取模块,通过IOCContainer实现

using System;
using UnityEngine;

namespace QFramework.Example
{
    public class IOCContainerExample : MonoBehaviour
    {
        
        public class SomeService
        {
            public void Say()
            {
                Debug.Log("SomeService Say Hi");
            }
        }
        
        
        public interface INetworkService
        {
            void Connect();
        }
        
        public class NetworkService : INetworkService
        {
            public void Connect()
            {
                Debug.Log("NetworkService Connect Succeed");
            }
        }

        private void Start()
        {
            var container = new IOCContainer();
            
            container.Register(new SomeService());
            
            container.Register<INetworkService>(new NetworkService());
            
            
            container.Get<SomeService>().Say();
            container.Get<INetworkService>().Connect();
        }
    }
}

// 输出结果:
// SomeService Say Hi
// NetworkService Connect Succeed

标签:Log,void,QFramework,class,Unity,Debug,new,___,public
From: https://www.cnblogs.com/lxp-blog/p/16949631.html

相关文章

  • 图数据库
    1前言图数据结构,能够很自然地表征现实世界。比如用户、门店、骑手这些实体可以用图中的点来表示,用户到门店的消费行为、骑手给用户的送餐行为可以用图中的边来表示。使用图的方式对场景建模,便于描述复杂关系。在美团,也有比较多的图数据存储及多跳查询需求,概括起来主要包括以下4......
  • 密码加密存储 登陆接口
    实际项目中我们不会把密码明文存储在数据库中。​默认使用的PasswordEncoder要求数据库中的密码格式为:{id}password。它会根据id去判断密码的加密方式。但是我们一般不会采用这种方式。所以就需要替换PasswordEncoder。​我们一般使用SpringSecurity为我们提供的BCryptPasswo......
  • SAP CRM 基础知识
    HANDSAPApril2018ZH              HANDCRM基础知识          HAND上海市青浦区汇联路33号            版权 上海汉得信息技术股份有限公司©2018版权......
  • Golang实现代理TCP客户端
    目标网站xxx.com,代理服务器xxxproxy.com,通过代理服务器实现流量转发。packagemainfunchandle(srcnet.Conn){dst,err:=net.Dial("tcp","xxx.com:80")iferr!=nil{log.Fatalln("Unabletoconnectoutunreachablehost")}deferd......
  • Halcon图像滤波&中值滤波&&高斯滤波&图像加减
    均值滤波:mean_image算子:mean_image(Image : ImageMean : MaskWidth, MaskHeight :)示例:mean_image(Image5,ImageMean1,3,3)Image5(输入对象):输入灰度图像ImageMean1(输出对象):输出均值滤波后的灰度图像3(输入控制参数1):均值矩阵的宽,数值通常为奇数,数值越大效果越明显3(输......
  • 为什么再html页面引用element复选框,只有名称值,没有复选框
    问题描述我引入了el-checkbox之后,发现浏览器页面只是显示里面的文字,并没有显示出来我想要看到的相应样式问题解决经过一定的百度查证可知,使用Element-UI组件时,我们需要用div标签将其包裹起来;然后使用script标签定义一下div里面的id属性,然后才能够引用到这个el-标签,让其中的样......
  • 给echarts添加点击事件
    1、在echarts内写上myChart.off('click')//防止多次触发,在给ehcart绑定事件时,要先写上此代码。myChart.on('click',(params)=>{   console.log(params) }) ......
  • 前端常用
    常用设计一个居中的代码<template><el-containerclass="container"><el-cardclass="box-card"><divclass="clearfix"><span>卡片名称</span><el-buttonstyle="float:right;pad......
  • Linux 环境,设置git账户密码,免登录
    1git配置个人用户信息#配置用户名gitconfig--globaluser.namewangjing#配置用户邮箱[email protected]#配置记住用户验证信息gitconfig--globalcredential.helperstore#查看相关配置信息gitconfig--lis  2保存账号2.1创建配......
  • 先Where 再First ,还是直接First.
    privatestaticvoidFirstTest(){IEnumerable<Item>items=newList<Item>(Enumerable.Range(0,1000).Select(a=>newItem(a)));//sortingrandomlyitems=items.OrderBy(x=>newGuid()).ToArray();......