之前一直在纠结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)