• 【Unity 框架】QFramework v1.0 使用指南 工具篇:04. ActionKit 时序动作执行系统 | Unity 游戏框架 | Unity 游戏开发 | Unity 独立游戏


    AciontKit 是一个时序动作执行系统。

    游戏中,动画的播放、延时、资源的异步加载、Tween 的执行、网络请求等,这些全部都是时序任务,而 ActionKit,可以把这些任务全部整合在一起,使用统一的 API,来对他们的执行进行计划

    OK,我们先看下 ActionKit的基本用法。

    延时回调

    示例代码如下:

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class DelayExample : MonoBehaviour
        {
            void Start()
            {
                Debug.Log("Start Time:" + Time.time);
                
                ActionKit.Delay(1.0f, () =>
                {
                    Debug.Log("End Time:" + Time.time);
                    
                }).Start(this);
            }
        }
    }
    
    // 输出结果
    // Start Time: 0
    // End Time: 1.00781
    

    序列和完成回调

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class SequenceAndCallback : MonoBehaviour
        {
            void Start()
            {
                Debug.Log("Sequence Start:" + Time.time);
    
                ActionKit.Sequence()
                    .Callback(() => Debug.Log("Delay Start:" + Time.time))
                    .Delay(1.0f)
                    .Callback(() => Debug.Log("Delay Finish:" + Time.time))
                    .Start(this, _ => { Debug.Log("Sequence Finish:" + Time.time); });
            }
        }
    }
    // 输出结果
    // Sequence Start:0
    // Delay Start:0
    // Delay Finish:1.00537
    // Sequence Finish:1.00537
    

    帧延时

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class DelayFrameExample : MonoBehaviour
        {
            void Start()
            {
                Debug.Log("Delay Frame Start FrameCount:" + Time.frameCount);
                
                ActionKit.DelayFrame(1, () => { Debug.Log("Delay Frame Finish FrameCount:" + Time.frameCount); })
                    .Start(this);
    
    
                ActionKit.Sequence()
                    .DelayFrame(10)
                    .Callback(() => Debug.Log("Sequence Delay FrameCount:" + Time.frameCount))
                    .Start(this);
    
                // ActionKit.Sequence()
                //      .NextFrame()
                //      .Start(this);
    
                ActionKit.NextFrame(() => { }).Start(this);
            }
        }
    }
    
    // 输出结果
    // Delay Frame Start FrameCount:1
    // Delay Frame Finish FrameCount:2
    // Sequence Delay FrameCount:11
    

    条件执行

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class ConditionExample : MonoBehaviour
        {
            private void Start()
            {
                ActionKit.Sequence()
                    .Callback(() => Debug.Log("Before Condition"))
                    .Condition(() => Input.GetMouseButtonDown(0))
                    .Callback(() => Debug.Log("Mouse Clicked"))
                    .Start(this);
            }
        }
    }
    
    // 输出结果
    // Before Condition
    // 鼠标左键按下后
    // Mouse Clicked
    

    重复执行

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class RepeatExample : MonoBehaviour
        {
            private void Start()
            {
                ActionKit.Repeat()
                    .Condition(() => Input.GetMouseButtonDown(0))
                    .Callback(() => Debug.Log("Mouse Clicked"))
                    .Start(this);
    
    
                ActionKit.Repeat(5)
                    .Condition(() => Input.GetMouseButtonDown(1))
                    .Callback(() => Debug.Log("Mouse right clicked"))
                    .Start(this, () =>
                    {
                        Debug.Log("Right click finished");
                    });
            }
        }
    }
    
    // 输出结果
    // 每次点击鼠标左键都会输出:Mouse Clicked 
    // 点击鼠标右键,只会输出五次:Mouse right clicked,第五次输出  Right click finished
    // 
    

    并行执行

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class ParallelExample : MonoBehaviour
        {
            void Start()
            {
                Debug.Log("Parallel Start:" + Time.time);
    
                ActionKit.Parallel()
                    .Delay(1.0f, () => { Debug.Log(Time.time); })
                    .Delay(2.0f, () => { Debug.Log(Time.time); })
                    .Delay(3.0f, () => { Debug.Log(Time.time); })
                    .Start(this, () =>
                    {
                        Debug.Log("Parallel Finish:" + Time.time);
                    });
            }
        }
    }
    
    // 输出结果
    // Parallel Start:0
    // 1.030884
    // 2.025135
    // 3.018883
    // Parallel Finish:3.018883
    

    更复杂的示例

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class ComplexExample : MonoBehaviour
        {
            private void Start()
            {
                ActionKit.Sequence()
                    .Callback(() => Debug.Log("Sequence Start"))
                    .Callback(() => Debug.Log("Parallel Start"))
                    .Parallel(p =>
                    {
                        p.Delay(1.0f, () => Debug.Log("Delay 1s Finished"))
                            .Delay(2.0f, () => Debug.Log("Delay 2s Finished"));
                    })
                    .Callback(() => Debug.Log("Parallel Finished"))
                    .Callback(() => Debug.Log("Check Mouse Clicked"))
                    .Sequence(s =>
                    {
                        s.Condition(() => Input.GetMouseButton(0))
                            .Callback(() => Debug.Log("Mouse Clicked"));
                    })
                    .Start(this, () =>
                    {
                        Debug.Log("Finish");
                        
                    });
            }
        }
    }
    
    // Sequence Start
    // Parallel Start
    // Delay 1s Finished
    // Delay 2s Finished
    // Parallel Finished
    // Check Mouse Clicked
    // 此时按下鼠标左键
    // Mouse Clicked
    // Finish
    

    自定义动作

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class CustomExample : MonoBehaviour
        {
            class SomeData
            {
                public int ExecuteCount = 0;
            }
    
            private void Start()
            {
                ActionKit.Custom(a =>
                {
                    a
                        .OnStart(() => { Debug.Log("OnStart"); })
                        .OnExecute(dt =>
                        {
                            Debug.Log("OnExecute");
    
                            a.Finish();
                        })
                        .OnFinish(() => { Debug.Log("OnFinish"); });
                }).Start(this);
                
                // OnStart
                // OnExecute
                // OnFinish
    
                ActionKit.Custom<SomeData>(a =>
                    {
                        a
                            .OnStart(() =>
                            {
                                a.Data = new SomeData()
                                {
                                    ExecuteCount = 0
                                };
                            })
                            .OnExecute(dt =>
                            {
                                Debug.Log(a.Data.ExecuteCount);
                                a.Data.ExecuteCount++;
    
                                if (a.Data.ExecuteCount >= 5)
                                {
                                    a.Finish();
                                }
                            }).OnFinish(() => { Debug.Log("Finished"); });
                    })
                    .Start(this);
                
                // 0
                // 1
                // 2
                // 3
                // 4
                // Finished
    
                // 还支持 Sequence、Repeat、Spawn 等
                // Also support sequence repeat spawn
                // ActionKit.Sequence()
                //     .Custom(c =>
                //     {
                //         c.OnStart(() => c.Finish());
                //     }).Start(this);
            }
        }
    }
    

    协程支持

    using System.Collections;
    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class CoroutineExample : MonoBehaviour
        {
            private void Start()
            {
                ActionKit.Coroutine(SomeCoroutine).Start(this);
                
                SomeCoroutine().ToAction().Start(this);
    
                ActionKit.Sequence()
                    .Coroutine(SomeCoroutine)
                    .Start(this);
            }
    
            IEnumerator SomeCoroutine()
            {
                yield return new WaitForSeconds(1.0f);
                Debug.Log("Hello:" + Time.time);
            }
        }
    }
    
    // 输出结果
    // Hello:1.002077
    // Hello:1.002077
    // Hello:1.002077
    

    全局 Mono 生命周期

    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class GlobalMonoEventsExample : MonoBehaviour
        {
            void Start()
            {
                ActionKit.OnUpdate.Register(() =>
                {
                    if (Time.frameCount % 30 == 0)
                    {
                        Debug.Log("Update");
                    }
                }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
                ActionKit.OnFixedUpdate.Register(() =>
                {
                    // fixed update code here
                    // 这里写 fixed update 相关代码
                }).UnRegisterWhenGameObjectDestroyed(gameObject);
                
                ActionKit.OnLateUpdate.Register(() =>
                {
                    // late update code here
                    // 这里写 late update 相关代码
                }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
                ActionKit.OnGUI.Register(() =>
                {
                    GUILayout.Label("See Example Code");
                    GUILayout.Label("请查看示例代码");
                }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
                ActionKit.OnApplicationFocus.Register(focus =>
                {
                    Debug.Log("focus:" + focus);
                }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
                ActionKit.OnApplicationPause.Register(pause =>
                {
                    Debug.Log("pause:" + pause);
                }).UnRegisterWhenGameObjectDestroyed(gameObject);
    
                ActionKit.OnApplicationQuit.Register(() =>
                {
                    Debug.Log("quit");
                }).UnRegisterWhenGameObjectDestroyed(gameObject);
            }
        }
    }
    

    DOTween 集成

    需要先提前装好 DOTween。

    然后导入 Example 中的如下包。

    image.png

    导入之后,就可以用 让 ActionKit 跑 DOTween 了,代码如下:

    using DG.Tweening;
    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class DOTweenExample : MonoBehaviour
        {
            private void Start()
            {
                // 使用 Custom 就可以方便接入
                // Just Use Custom 
                ActionKit.Custom(c =>
                {
                    c.OnStart(() => { transform.DOLocalMove(Vector3.one, 0.5f).OnComplete(c.Finish); });
                }).Start(this);
                
                // 也可以自定义 IAction
                // Also implement with IAction
                DOTweenAction.Allocate(() => transform.DOLocalRotate(Vector3.one, 0.5f))
                    .Start(this);
                
                // 使用 ToAction
                // Use ToAction
                DOVirtual.DelayedCall(2.0f, () => LogKit.I("2.0f")).ToAction().Start(this);
    
                // 链式 API 支持
                // fluent api support
                ActionKit.Sequence()
                    .DOTween(() => transform.DOScale(Vector3.one, 0.5f))
                    .Start(this);
            }
        }
        
      
    }
    

    UniRx 集成

    需要先提前装好 UniRx。

    然后导入 Example 中的如下包。

    image.png

    导入成功后,使用示例如下:

    using System;
    using UniRx;
    using UnityEngine;
    
    namespace QFramework.Example
    {
        public class UniRxExample : MonoBehaviour
        {
            void Start()
            {
                // 可以直接使用 Custom
                // directly use custom
                ActionKit.Custom(c =>
                {
                    c.OnStart(() => { Observable.Timer(TimeSpan.FromSeconds(1.0f)).Subscribe(_ => c.Finish()); });
                }).Start(this, () => LogKit.I("1.0f"));
    
                // 使用 UniRxAction 不方便...
                // Use UniRxAction 
                UniRxAction<long>.Allocate(() => Observable.Timer(TimeSpan.FromSeconds(2.0f))).Start(this,()=>LogKit.I("2.0f"));
    
    
                // 使用 ToAction 方便易用
                // Use ToAction
                Observable.Timer(TimeSpan.FromSeconds(3.0f)).ToAction().Start(this, () => LogKit.I("3.0f"));
    
                ActionKit.Sequence()
                    .UniRx(() => Observable.Timer(TimeSpan.FromSeconds(4.0f)))
                    .Start(this, () => LogKit.I("4.0f"));
            }
        }
     
    }
    

    好了,关于 ActionKit 的介绍就到这里。

    更多内容

  • 相关阅读:
    [LeetCode] Most Profit Assigning Work 安排最大利润的工作
    [LeetCode] Friends Of Appropriate Ages 适合年龄段的朋友
    [LeetCode] Goat Latin 山羊拉丁文
    [LeetCode] Binary Trees With Factors 带因子的二叉树
    [LeetCode] Card Flipping Game 翻卡片游戏
    [AWS] Nginx Started but not Serving AWS上Nginx服务器无法正常工作
    [LeetCode] Shortest Distance to a Character 到字符的最短距离
    [LeetCode] Short Encoding of Words 单词集的短编码
    [LeetCode] Most Common Word 最常见的单词
    Solve Error: MissingSchemaError: Schema hasn't been registered for model "YourModel".
  • 原文地址:https://www.cnblogs.com/liangxiegame/p/16798706.html
Copyright © 2020-2023  润新知