思路
想在lua中写一个Unity协程效果的函数,延时N秒触发。无奈lua中没有提供封装好的函数调用。
最开始的思路是利用lua的协程,在thread中调用sleep之类的方法,之前做安卓开发的时候就用类似的思路实现的。
结果百度了一圈,网上有四种方法实现sleep的效果。
4种方法转载自 https://blog.csdn.net/charlie_2010/article/details/6719891
方法1
--在一个死循环中设置一个跳出条件,但是这样的做法会占用大量CPU资源,强烈不推荐使用哦
function sleep(n)
local t0 = os.clock()
while os.clock() - t0 <= n do end
end
方法2
--在一个死循环中设置一个跳出条件,但是这样的做法会占用大量CPU资源,强烈不推荐使用哦
function sleep(n)
os.execute("sleep " .. n)
end
方法3
--虽然Windows没有内置sleep命令,但是我们可以稍微利用下ping命令的性质
function sleep(n)
if n > 0 then os.execute("ping -n " .. tonumber(n + 1) .. " localhost > NUL") end
end
方法4
--使用socket库中select函数,可以传递0.1给n,使得休眠的时间精度达到毫秒级别。
require("socket")
function sleep(n)
socket.select(nil, nil, n)
end
总结起来就是方法1消耗太高,方法2,方法3不能用,方法4调用后卡在了socket.select()里也没了结果。
最终还是借助Unity引擎的update生命周期来实现。
1.封装一个模块记录一些延时任务,循环任务
2.用Unity调用模块中的Update接口,实现lua内部计时器
代码
Timer ={
timerTasks={};--延时任务
timerLoopTasks={};--延时循环任务
taskIndex=1;--任务编号
};
--设置延时循环函数 id,初次延时,循环后间隔延时,循环时间,循环函数,结束时回调函数
function Timer:SetDelayLoopFunction(delayTime, delayTime1, loopTime, funcLoop,funcOnFinish)
if self.timerLoopTasks[self.taskIndex] == nil then
self.timerLoopTasks[self.taskIndex] = {};
end
self.timerLoopTasks[self.taskIndex].startTime=CS.UnityEngine.Time.time+delayTime;--触发时机
self.timerLoopTasks[self.taskIndex].loopDelay=delayTime1;--每次循环的间隔
self.timerLoopTasks[self.taskIndex].overTime=CS.UnityEngine.Time.time+loopTime+delayTime;--循环持续时间
self.timerLoopTasks[self.taskIndex].funcLoop=funcLoop;--循环函数
self.timerLoopTasks[self.taskIndex].funcOnFinish=funcOnFinish;--结束时回调函数
self.taskIndex=self.taskIndex+1;
return self.taskIndex-1;
end
--延时函数 id,延时时间,触发方法
function Timer:SetDelayFunction(delayTime, func)
if self.timerTasks[self.taskIndex] == nil then
self.timerTasks[self.taskIndex] = {};
end
self.timerTasks[self.taskIndex].func = func;
self.timerTasks[self.taskIndex].startTime = CS.UnityEngine.Time.time + delayTime;
self.taskIndex=self.taskIndex+1;
return self.taskIndex-1;
end
--更新
function Timer:Update()
for k, v in pairs(self.timerTasks) do
--满足延时条件 触发
if v.startTime < CS.UnityEngine.Time.time then
if v.func~=nil then
v.func();--延时方法
end
self.timerTasks[k]=nil;--回收任务
end
end
for k,v in pairs(self.timerLoopTasks) do
--过期任务
if v.overTime < CS.UnityEngine.Time.time then
if v.funcOnFinish~=nil then
v.funcOnFinish();--循环方法结束回调
end
self.timerLoopTasks[k]=nil;--回收任务
--有效任务
else
--满足触发条件
if v.startTime < CS.UnityEngine.Time.time then
if v.funcLoop~=nil then
v.funcLoop();--循环方法
end
v.startTime=v.startTime+v.loopDelay;--设置下一次触发时间
end
end
end
end
--撤销任务
function Timer:Remove(id)
for k,v in pairs(self.timerTasks) do
if k==id then
self.timerTasks[id]=nil;
return;
end
end
for k,v in pairs(self.timerLoopTasks) do
if k==id then
self.timerLoopTasks[id]=nil;
return;
end
end
end
--清理
function Timer:Clear()
for k, v in pairs(self.timerTasks) do
self.timerTasks[k] = nil;
end
for k, v in pairs(self.timerLoopTasks) do
self.timerLoopTasks[k] = nil;
end
self.taskIndex=1;
end
效果、
修改了代码,id改为内部自动创建