从零开始搭xlua框架(三)实现类似C#UnityEngine.MonoBehaviour.Invoke

之前一直在纠结lua里面没有invoke这个函数 很不方便 就一直在网上找lua中的延迟调用函数
发现根本就没有 我想要的答案 后来跑xlua的交流群里面去问了一下 终于有人给解决方案了
实际上很简单的一件事 只是自己有点死脑壳 想不通
解决方案: C#端实现 定时器 给lua调用就好了
C#端

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

namespace LuaCallCSharpSpace
{
    /// <summary>
    /// 定时器
    /// </summary>

    public class Scheduler : MonoSingleton<Scheduler>
    {
        class SchedulerInfo
        {
            /* isUpdate权重大于isOnce */

            //callback
            public Action action;
            //是否活动
            public bool isActivity;
            //是否只执行一次
            public bool isOnce;
            //是否每帧执行一次
            public bool isUpdate;
            //倒计时后的间隔时间
            public float intervalTime;
            //当前倒计时
            public float countDown;
            //是否无视TimeScale
            public bool isIgnoreTimeScale;
        }

        private List<SchedulerInfo> _actions = new List<SchedulerInfo>();
        private SchedulerInfo tmpInfo;

        /// <summary>
        /// 间隔定时器
        /// </summary>
        /// <param name="action">每次执行的操作</param>
        /// <param name="time">开始时间</param>
        /// <param name="rate">间隔时间</param>

        public void Run(Action action, float time, float rate, bool isIgnoreTimeScale = false)
        {
            SchedulerInfo info = new SchedulerInfo();
            info.action = action;
            info.countDown = time;
            info.intervalTime = rate;
            info.isActivity = true;
            info.isOnce = false;
            info.isUpdate = false;
            info.isIgnoreTimeScale = isIgnoreTimeScale;
            _actions.Add(info);
        }

        /// <summary>
        /// 运行一次的定时器
        /// </summary>
        /// <param name="action">执行的操作</param>
        /// <param name="time">开始时间</param>
        public void RunOnce(Action action, float time, bool isIgnoreTimeScale = false)
        {
            if (action == null) return;
            SchedulerInfo info = new SchedulerInfo();
            info.action = action;
            info.countDown = time;
            info.isActivity = true;
            info.isOnce = true;
            info.isUpdate = false;
            info.isIgnoreTimeScale = isIgnoreTimeScale;
            _actions.Add(info);
        }

        /// <summary>
        /// 每帧执行的定时器
        /// </summary>
        /// <param name="action">每帧执行的操作</param>
        public void RunUpdate(Action action)
        {
            if (action == null) return;
            SchedulerInfo info = new SchedulerInfo();
            info.action = action;
            info.isActivity = true;
            info.isUpdate = true;
            _actions.Add(info);
        }

        /// <summary>
        /// 暂停定时器
        /// </summary>
        public void Pause(Action action)
        {
            if (action == null) return;
            SchedulerInfo needPauseScheduler = this._actions.Find(p => p.action.Equals(action));
            if (needPauseScheduler != null) needPauseScheduler.isActivity = false;
        }

        /// <summary>
        /// 暂停所有定时器
        /// </summary>
        public void PauseAll()
        {
            for (int i = 0; i < this._actions.Count; i++)
            {
                _actions[i].isActivity = false;
            }
        }


        public bool IsHaveAction(Action action)
        {
            if (action == null) return false;
            SchedulerInfo needResumeScheduler = this._actions.Find(p => p.action.Equals(action));
            if (needResumeScheduler != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 恢复定时器
        /// </summary>
        public void Resume(Action action)
        {
            if (action == null) return;
            SchedulerInfo needResumeScheduler = this._actions.Find(p => p.action.Equals(action));
            if (needResumeScheduler != null) needResumeScheduler.isActivity = true;
        }

        /// <summary>
        /// 恢复所有定时器
        /// </summary>
        public void ResumeAll()
        {
            for (int i = 0; i < this._actions.Count; i++)
            {
                _actions[i].isActivity = true;
            }
        }

        /// <summary>
        /// 注销定时器
        /// </summary>
        public void Unschedule(Action action)
        {
            if (action == null) return;
            SchedulerInfo removeScheduler = this._actions.Find(p => p.action.Equals(action));
            if (removeScheduler != null) this._actions.Remove(removeScheduler);
        }

        public void UnscheduleAll()
        {
            this._actions.Clear();
        }

        private void Start()
        {
            DontDestroyOnLoad(this.gameObject);
        }

        void Update()
        {
            if (this._actions.Count == 0) return;
            for (int i = this._actions.Count - 1; i >= 0; i--)
            {
                tmpInfo = this._actions[i];
                if (!tmpInfo.isActivity) continue;

                if (tmpInfo.isUpdate)
                {
                    tmpInfo.action();
                    continue;
                }

                tmpInfo.countDown -= (tmpInfo.isIgnoreTimeScale ? Time.unscaledDeltaTime : Time.deltaTime);

                if (tmpInfo.isOnce)
                {
                    if (tmpInfo.countDown <= 0)
                    {
                        this._actions.Remove(tmpInfo);
                        tmpInfo.isActivity = false;
                        tmpInfo.action();
                    }
                    continue;
                }
                else
                {
                    if (tmpInfo.countDown <= 0)
                    {
                        tmpInfo.action();
                        tmpInfo.countDown = tmpInfo.intervalTime;
                    }
                }
            }
        }
    }
}

当然这个命名空间我是自动化 [LuaCallCSharp]配置了的

自动化配置代码

using System.Collections.Generic;
using System;
using System.Linq;
using System.Reflection;
using XLua;
public class CSharp_Lua_Mutual  {
    static List<string> exclude = new List<string> {
        "HideInInspector", "ExecuteInEditMode",
        "AddComponentMenu", "ContextMenu",
        "RequireComponent", "DisallowMultipleComponent",
        "SerializeField", "AssemblyIsEditorAssembly",
        "Attribute", "Types",
        "UnitySurrogateSelector", "TrackedReference",
        "TypeInferenceRules", "FFTWindow",
        "RPC", "Network", "MasterServer",
        "BitStream", "HostData",
        "ConnectionTesterStatus", "GUI", "EventType",
        "EventModifiers", "FontStyle", "TextAlignment",
        "TextEditor", "TextEditorDblClickSnapping",
        "TextGenerator", "TextClipping", "Gizmos",
        "ADBannerView", "ADInterstitialAd",
        "Android", "Tizen", "jvalue",
        "iPhone", "iOS", "Windows", "CalendarIdentifier",
        "CalendarUnit", "CalendarUnit",
        "ClusterInput", "FullScreenMovieControlMode",
        "FullScreenMovieScalingMode", "Handheld",
        "LocalNotification", "NotificationServices",
        "RemoteNotificationType", "RemoteNotification",
        "SamsungTV", "TextureCompressionQuality",
        "TouchScreenKeyboardType", "TouchScreenKeyboard",
        "MovieTexture", "UnityEngineInternal",
        "Terrain", "Tree", "SplatPrototype",
        "DetailPrototype", "DetailRenderMode",
        "MeshSubsetCombineUtility", "AOT", "Social", "Enumerator",
        "SendMouseEvents", "Cursor", "Flash", "ActionScript",
        "OnRequestRebuild", "Ping",
        "ShaderVariantCollection", "SimpleJson.Reflection",
        "CoroutineTween", "GraphicRebuildTracker",
        "Advertisements", "UnityEditor", "WSA",
        "EventProvider", "Apple",
        "ClusterInput", "Motion",
        "UnityEngine.UI.ReflectionMethodsCache", "NativeLeakDetection",
        "NativeLeakDetectionMode", "WWWAudioExtensions", "UnityEngine.Experimental",
    };
    static bool isExcluded(Type type)
    {
        var fullName = type.FullName;
        for (int i = 0; i < exclude.Count; i++)
        {
            if (fullName.Contains(exclude[i]))
            {
                return true;
            }
        }
        return false;
    }
    [LuaCallCSharp]
    public static IEnumerable<Type> LuaCallCSharp
    {
        get
        {
            List<string> namespaces = new List<string>() // 在这里添加名字空间
            {
                "LuaCallCSharpSpace",
             
            };
            var unityTypes = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                              where !(assembly.ManifestModule is System.Reflection.Emit.ModuleBuilder)
                              from type in assembly.GetExportedTypes()
                              where type.Namespace != null && namespaces.Contains(type.Namespace) && !isExcluded(type)
                                      && type.BaseType != typeof(MulticastDelegate) && !type.IsInterface && !type.IsEnum
                              select type);

            string[] customAssemblys = new string[] {
                "Assembly-CSharp",
            };
            var customTypes = (from assembly in customAssemblys.Select(s => Assembly.Load(s))
                               from type in assembly.GetExportedTypes()
                               where type.Namespace == null || !type.Namespace.StartsWith("XLua")
                                       && type.BaseType != typeof(MulticastDelegate) && !type.IsInterface && !type.IsEnum
                               select type);
            return unityTypes.Concat(customTypes);
        }
    }

}

完了lua想用直接调用就好了例如

function testDelayFuc()
  print("延迟调用")
end

CS.LuaCallCSharpSpace.Scheduler.Instance:Run(testDelayFuc,0,1)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值