QFramework框架学习

news2025/1/4 17:13:25

主要学习内容

  1. TypeEventSystem

  1. ActionKit

  1. Timer类

1、TypeEventSystem-适用于一个条件触发,多个组件响应的情况

例如:动物园系统中,点击肉食动物按钮,动物园中有肉食属性的动物都进行显示。

步骤:

1、动物自身脚本上进行判断是否有肉食属性,有则注册事件

2、事件发送方:按钮点击,发送通知事件

3、事件接收方:动物,执行处理事件的操作

①单事件触发

代码学习

using System;
using System.Collections;
using System.Collections.Generic;
using QFramework;
using UnityEngine;

// namespace QFramework.Example//在类的外面嵌套上命名空间
// {
    public class TypeEventSystemController : MonoBehaviour
    {
        
        //用结构体定义一个事件,适合一对多的情况,一触发,多响应
        public struct EventA
        {
            //参数
            public int Count;
        }

        //在start中监听事件
        void Start()
        {
            //注册并回调,简单写法
            TypeEventSystem.Global.Register<EventA>(e => //输入e点击Tab
            {
                Debug.Log(e.Count);
            }).UnRegisterWhenGameObjectDestroyed(gameObject);//注销,与当前的gameobject进行关联
            //传统事件机制的用法①②③
            //①TypeEventSystem.Global.Register<EventA>(onEventA);
        }

        //②
        //void onEventA(Event e)
        //{
        //}
        //③销毁
        //private void OnDestroy()
        //{
        //    TypeEventSystem.Global.UnRegister<EventA>(onEventA);
        // }
       
        // Update is called once per frame
        void Update()
        {
            //发送事件
            if (Input.GetMouseButtonDown(0))
            {
                //第一种写法:自动new一个A,但是无法传参
                //TypeEventSystem.Global.Send<EventA>();
                //第二种写法
                TypeEventSystem.Global.Send(new EventA()
                {
                    Count = 10
                });
            }
        }

      
    }
// }

②多事件触发

using System.Collections;
using System.Collections.Generic;
using QFramework;
using SnakeGame;
using Unity.VisualScripting;
using UnityEngine;

public class MutiEvent : MonoBehaviour
    //添加
    // IOnEvent<MutiEvent.IEventA>, 
    //     IOnEvent<MutiEvent.EventB>//报错可进行点击自动生成代码
{

    public interface IEventA//接口形式
    {
            
        public abstract void Function();
    }

    public struct EventB: IEventA
    {
        public void Function()
        {
            print("从管道B中流出");
        }
    }

    public struct EventC: IEventA
    {
        public void Function()
        {
            print("从管道C中流出");
        }
    }
        
        
    void Start()
    {
        TypeEventSystem.Global.Register<IEventA>(a => 
        {
            Debug.Log(a.GetType().Name);
        }).UnRegisterWhenGameObjectDestroyed(gameObject); //输出名字
          
    }


    // Update is called once per frame
    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
                
            TypeEventSystem.Global.Send<IEventA>(new EventB());
             
        }

        if (Input.GetMouseButtonDown(1))
        {
            TypeEventSystem.Global.Send<IEventA>(new EventC());
        }
    }

}

2、ActionKit

①单独使用时

1)延时功能
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using QFramework;

public class ActionKitExample : MonoBehaviour
{
    void Start()
    {
        //调用延时功能
         DelayTime();
    }
   
    /// <summary>
    /// 实现延时功能
    /// </summary>

    void DelayTime()
    {
        print("开始时间 "+Time.time);
        ActionKit.Delay(1.0f, () =>
        {
            print("延迟时间:" + Time.time);
        }).Start(this);//底层使用的是MonoBehaviour中的东西,所以需要关联一下gameObject
    }
 }

运行结果:大约延迟1s

 /// <summary>
    /// 序列和完成回调
    /// </summary>
    void SequenceAndCallBack()
    {
        print("序列开始:"+Time.time);
            
        ActionKit.Sequence()
            .Callback(() => print("DelayStart延时开始:"+Time.time))//回调函数
            .Delay(1.0f)//延时一秒
            .Callback(()=>Debug.Log("Delay Finish延时结束:"+Time.time))
            .Start(this,_=>{print("Sequence Finish序列结束:"+Time.time);});
    }

运行结果:sequence从上到下执行

  /// <summary>
    /// 帧延时
    /// </summary>
    void DelayFrameExample()
    {
        //延时一帧后回调
        print("帧延时开始帧率数"+Time.frameCount);
        ActionKit.DelayFrame(1, () =>
        {
            print("帧延时结束帧率数" + Time.frameCount);
        }).Start(this);

        //序列延时10帧后回调
        ActionKit.Sequence()
            .DelayFrame(10)
            .Callback(() => print("序列延时帧率数" + Time.frameCount))
            .Start(this);

        //下一帧做什么
        ActionKit.NextFrame(() => { }).Start(this);
    }

运行结果

   /// <summary>
    /// 支持协程的方式
    /// </summary>
    void CoroutineExample()
    {
        //第一种:普通
        //ActionKit.Coroutine(() => SomeCoroutine()).Start(this);
        //ActionKit.Coroutine(SomeCoroutine).Start(this);
        //第二种:将协程转换为动作
        //SomeCoroutine().ToAction().Start(this);
        //第三种:序列的方式执行
        ActionKit.Sequence()
            .Coroutine(()=>SomeCoroutine())
            .Callback(()=>print("结束"))//如果是多个:使用delegte
            .Start(this);
    }
        
    IEnumerator SomeCoroutine()
    {
        yield  return new WaitForSeconds(1.0f);
        print("你好"+Time.time);
    }

运行结果:我感觉跟上面序列完成回调的Delay(1.0f)方法是一样的,且不如上面的简单,这个方法可以弃用了

2)条件执行
    /// <summary>
    /// 条件执行(仅执行一次)
    /// </summary>
    void ConditionExample()
    {
        ActionKit.Sequence()
            .Callback(() => print("条件发生之前"))
            .Condition(() => Input.GetMouseButtonDown(0))//每帧调用后面的委托,直到委托返回为true,执行下一步
            .Callback(() => print("鼠标点击"))
            .Start(this);
    }

运行结果:一直在等待条件的执行

   /// <summary>
    /// 重复执行
    /// </summary>
    void RepeatExample()
    {
        print("点击五次鼠标右键,输出信息");
        ActionKit.Repeat(5)//改为关键字repeat
            .Condition(() => Input.GetMouseButtonDown(1))//每帧调用后面的委托,直到委托返回为true,执行下一步
            .Callback(() => print("鼠标点击"))
            .Start(this, () =>
            {
                print("5次右键点击完成");
            });
    }

运行结果:条件重复5次后输出

  /// <summary>
    /// 并行执行,同时执行动作,动作全部完成执行最后finish函数
    /// </summary>
    void ParallelExample()
    {
        print("并行开始");
        ActionKit.Parallel()
            .Delay(1.0f, () => { print(Time.time); })
            .Delay(2.0f, () => { print(Time.time); })
            .Delay(3.0f, () => { print(Time.time); })
            .Start(this, () =>
            {
                print("并行结束" + Time.time);
            });
    }

运行结果

3)自定义动作执行
    /// <summary>
    ///自定义动作
    /// </summary>
    void CutomExample()
    {
        ActionKit.Custom(a =>
        {
            a
                .OnStart(() => { print("OnStart"); })
                .OnExecute(dt =>
                {
                    print("OnExecute");
                    if (Time.frameCount > 5)
                    {
                        a.Finish();//注意这里是Finish
                    }
                })
                .OnFinish(() => { print("OnFinish"); });
        }).Start(this);
    }
        

运行结果:事件开始,执行,结束

  //传数据的自定义事件
    public class ActionData
    {
        public  int FrameCount;//公有,其他函数可以访问
    }
    
       
    /// <summary>
    ///自定义动作,含参数
    /// </summary>
    void CutomExampleWithParameter()
    {
        ActionKit.Custom<ActionData>(a =>//传一个自定义的数据类型
        {
            a.OnStart(() =>
                {
                    a.Data = new ActionData()
                    {
                        FrameCount=0
                    };
                    print("OnStart");
                })
                .OnExecute(dt =>
                {
                    print("OnExecute");
                    a.Data.FrameCount++;
                    if (a.Data.FrameCount > 5)
                    {
                        a.Finish();//注意这里是Finish
                    }
                })
                .OnFinish(() => { print("OnFinish"); });
        }).Start(this);
    }

运行结果:开始的时候定义参数值,执行时进行判断,符合条件结束

②与DoTween插件集成

集成步骤:

查找-双击-导入

代码

    /// <summary>
    /// DoTween的集成,Dotween和ActionKit组合使用
    /// </summary>

    void DotweenExample()
    {
         ActionKit.Sequence()
             .DOTween(() => transform.DOMoveX(5, 1))
             .Start(this);
    }
        

运行结果:挂在脚本的物体在一秒钟,x变为5

3、Timer计时器

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using QFramework;
using QFramework.TimeExtend;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;
using Timer = QFramework.TimeExtend.Timer;

public class Test : MonoBehaviour
{
    private Timer timer1;
    private Timer timer2;
    public Text timeText;
    
    void Start()
    {
        ActionKit.Sequence()
            .Callback(() => print("按下F1新建一个计时器"))
            .Condition(() => Input.GetKey(KeyCode.F1)) 
            .Callback(() => timer1 = Timer.AddTimer(10, "Timer1", false, true)
                .OnUpdated(a =>
                {
                    timeText.text = ((1 - a) * 10).ToString();
                })
                .OnCompleted(() => //十秒完成后
                {
                    print("Timer1计时10秒结束");
                }))
            .Condition(()=> Input.GetKey(KeyCode.D))
            .Callback(delegate
                {
                    Timer.DelTimer("Timer1");
                    print("删除-计时器1");
                }
            )
            .Condition(()=>  Input.GetKey(KeyCode.A))
            .Callback(delegate
                {
                    if (!Timer.Exist(timer2))
                    {
                        timer2 = Timer.AddTimer(10, "Timer2", false, true)
                            .OnUpdated(a =>
                            {
                                timeText.text = (a*10).ToString();
                            })
                            .OnCompleted(()=>//十秒完成后
                            {
                                print("Timer2计时10秒结束");
                            });
                        print("新建-计时器2");
                    }
                }
            )   
            .Condition(() => Input.GetKey(KeyCode.S)) 
            .Callback(delegate
                {
                    if (Timer.Exist(timer2))
                    {
                        Timer.Pause(timer2);
                        print("暂停-计时器2");
                    }
                }
            )   
            .Condition(() => Input.GetKey(KeyCode.F)) 
            .Callback(delegate
                {
                    if (Timer.Exist(timer2))
                    {
                        Timer.Resum(timer2);
                        print("计时器恢复");
                    }
                   
                }
            )   
            .Start(this);
      
    }
    
    }
}

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

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

相关文章

产品的可持续发展

如今&#xff0c;产品的可持续性对于取得商业成功至关重要。越来越多的政府提出了相关的合规性要求&#xff0c;普通消费者也在翘首期待符合可持续性发展理念的产品上市。然而&#xff0c;许多企业面临的首要问题是如何确定他们的产品是否满足可持续性发展的要求。 毕竟&#x…

后量子 KEM 方案:LAC

参考文献&#xff1a; Lyubashevsky V, Peikert C, Regev O. On ideal lattices and learning with errors over rings[J]. Journal of the ACM (JACM), 2013, 60(6): 1-35.Lu X, Liu Y, Zhang Z, et al. LAC: Practical ring-LWE based public-key encryption with byte-leve…

java -数据结构,List相关基础知识,ArrayList的基本使用,泛型的简单、包装类介绍

一、 预备知识-泛型(Generic) 1.1、泛型的引入 比如&#xff1a;我们实现一个简单的顺序表 class MyArrayList{public int[] elem;public int usedSize;public MyArrayList(){this.elem new int[10];}public void add(int key){this.elem[usedSize] key;usedSize;}public …

Ethercat系列(4)Twcat3激活配置过程的协议分析

广播设置ESC的4个端口环路设置从-》主广播读从站状态机实际状态主-》从从-》主广播清除接收错误计数器0x300且读应用层状态从-》主顺序读从站基本信息&#xff0c;链路层配置与状态从-》主广播读从站状态机状态主-》从从-》主顺序写ESC控制模式&#xff0c;广播读从站状态主-》…

一、图机器学习导论【CS224W】(Datawhale组队学习)

开源内容&#xff1a;https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频&#xff1a;https://space.bilibili.com/1900783/channel/collectiondetail?sid915098 斯坦福官方课程主页&#xff1a;https://web.stanford.edu/class/cs224w 文章目录前…

C++中的标准输入和输出

一、 C 输入输出的含义 在C语言中我们的输入和输出都是以printf和scanf进行操作的。他们都是函数。在C中的我们的输入输出都是以终端为对象的&#xff0c;即从键盘输入数据&#xff0c;运行结果输出到显示器屏幕上。从操作系统(Linux)的角度看&#xff0c;每一个与主机相连的输…

RKE2部署高可用Rancher v2.7.1

先决条件 注意修改主机名&#xff0c;不要有冲突 第一个server节点安装 官方文档的描述感觉对于新手来说太不友好了&#xff0c;建议以下链接都看一下。Rancher新老文档都建议看一下&#xff0c;不然刚刚入门很蒙。 RKE2快速开始&#xff1a;https://docs.rke2.io/zh/install…

html+css综合练习一

文章目录一、小米注册页面1、要求2、案例图3、实现效果3.1、index.html3.2、style.css二、下午茶页面1、要求2、案例图3、index.html4、style.css三、法国巴黎页面1、要求2、案例图3、index.html4、style.css一、小米注册页面 1、要求 阅读下列说明、效果图&#xff0c;进行静…

由浅入深,聊聊OkHttp的那些事(很长,很细节)

引言 在 Android 开发的世界中&#xff0c;有一些组件&#xff0c;无论应用层技术再怎么迭代&#xff0c;作为基础支持&#xff0c;它们依然在那里。 比如当我们提到网络库时&#xff0c;总会下意识想到一个名字&#xff0c;即 OkHttp 。 尽管对于大多数开发者而言&#xff0…

spark02-内存数据分区分配原理

代码&#xff1a;val conf: SparkConf new SparkConf().setMaster("local[*]").setAppName("wordcount") val scnew SparkContext(conf) //[1] [2,3] [4,5] val rdd: RDD[Int] sc.makeRDD(List(1,2,3,4,5),3) //将处理的数据保存分区文件 rdd.saveAsText…

【Apifox Helper】自动生成接口文档,IDEA+Apifox懒人必备

文章目录前言&#x1f34a;缘由接口文档对接爽&#xff0c;整理起来真费脑⏲️本文阅读时长约10分钟&#x1f96e;前置条件1. IDEA开发工具2. Apifox(不必要)&#x1f3af;主要目标一秒生成接口文档&#x1f369;水图IDEA中项目接结构图生成到Apifox接口文档图&#x1f468;‍&…

Django框架之模板系列

模板 思考 : 网站如何向客户端返回一个漂亮的页面呢&#xff1f; 提示 : 漂亮的页面需要html、css、js.可以把这一堆字段串全都写到视图中, 作为HttpResponse()的参数,响应给客户端. 问题 : 视图部分代码臃肿, 耦合度高.这样定义的字符串是不会出任何效果和错误的.效果无法及时…

论文投稿指南——中文核心期刊推荐(矿业工程)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

springMVC概念(第一个入门案例)

目录 一、概念 1.什么是mvc&#xff1f; 2.mvc的工作流程&#xff1f; 3.什么是springMVC&#xff1f; 4.springMVC的特点 二、入门案例 准备工作&#xff1a; 正式代码例子 &#xff1a; 一、概念 1.什么是mvc&#xff1f; 答&#xff1a;MVC是一种软件架构的思想&a…

leaflet 上传包含shp的zip文件,在map上解析显示图形(059)

第059个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中本地上传包含shp的zip文件,利用shapefile读取shp数据,并在地图上显示图形。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果 文章目录 示例效果加载shapefile.js方式安装引用jszip(…

大数据框架之Hadoop:HDFS(四)HDFS的数据流(面试重点)

4.1HDFS写数据流程 4.1.1 剖析文件写入 HDFS写数据流程&#xff0c;如下图所示。 1&#xff09;客户端通过 Distributed FileSystem 模块向 NameNode 请求上传文件&#xff0c;NameNode检查目标文件是否已存在&#xff0c;父目录是否存在。 2&#xff09;NameNode 返回是否可…

c++函数指针进阶

c中有两种函数指针 普通函数指针成员函数指针 而对于成员函数指针&#xff0c;又分为两种 静态成员函数指针非静态成员函数指针 定义普通函数指针与静态函数指针的语法类似 void (*pa)(); 定义非静态成员函数指针 void (A::* pa)(); 在调用非静态成员函数时&#xff0c;实…

Spring循环依赖问题,Spring是如何解决循环依赖的?

文章目录一、什么是循环依赖1、代码实例2、重要信息二、源码分析1、初始化Student对Student中的ClassRoom进行Autowire操作2、Student的自动注入ClassRoom时&#xff0c;又对ClassRoom的初始化3、ClassRoom的初始化&#xff0c;又执行自动注入Student的逻辑4、Student注入Class…

8. QT_OpenGL--1. 在QtWidget中搭建OpenGL加载框架

1. 说明&#xff1a; 在 Qt 中使用 OpenGL&#xff0c;实际上时严格遵循一种代码开发框架的&#xff0c;在 QtWidget 中&#xff0c;需要使用 openGlWidget 控件&#xff0c;并自定义类&#xff0c;类中还需继承 QOpenGLWidget,QOpenGLFunctions_3_3_Core 两个类&#xff0c;并…

Word控件Spire.Doc 【Table】教程(14): 如何在C#中为word表格设置AutoFit选项

Spire.Doc for .NET是一款专门对 Word 文档进行操作的 .NET 类库。在于帮助开发人员无需安装 Microsoft Word情况下&#xff0c;轻松快捷高效地创建、编辑、转换和打印 Microsoft Word 文档。拥有近10年专业开发经验Spire系列办公文档开发工具&#xff0c;专注于创建、编辑、转…