//Lua文件名字 这个是个.bytes后缀的文本 跟xlu里面用txt文件放lua代码一样外面拖拽赋值 public TextAsset luaFile = null; //Lua状态 private LuaState lua = null; //这个类继承MonoBehaviour里面装的是一堆事件在Start里面获取事件 private LuaLooper looper = null; void Awake () { lua = new LuaState(); lua.Start(); //绑定操作绑定lua状态 //Unity里面的协程是要在脚本里面游戏对象身上进行调用的 //协程类似于生命周期里面的一个回调函数 执行的时间点是在Update之后LateUpdate之前 //所以如果要执行协程就要绑定在对象身上 LuaBinder.Bind(lua); //给自己添加上LuaLooper这个脚本 然后把这个脚本组件赋值给looper对象 looper = gameObject.AddComponent<LuaLooper>(); looper.luaState = lua;//设置looper对象的状态为lua //执行lua脚本 代码块 文件名字 lua.DoString(luaFile.text, "TestLuaCoroutine.lua"); //获取方法 LuaFunction f = lua.GetFunction("TestCortinue"); f.Call(); f.Dispose(); f = null; }
脚本功能,调用写在文本文件里面的lua协同程序
注:Lua 中的协程代表一个独立的执行线程,与多线程系统中的线程不同,协程仅通过显式调用 yield 函数来暂停其执行。
--对lua文件的说明 --斐波那契数列 function fib(n) local a, b = 0, 1 while n > 0 do a, b = b, a + b n = n - 1 end return a end --协程函数 function CoFunc() print('Coroutine started') for i = 0, 10, 1 do print(fib(i)) --等待0.1秒【这个是Tolua自己写的里面的具体实现方法下面有解释】 coroutine.wait(0.1) end print("current frameCount: "..Time.frameCount) --等一帧之后执行 coroutine.step() print("yield frameCount: "..Time.frameCount) --实例化一个WWW对象 网址是百度的官网【WWW目前在unity里面已经弃用了看看就行不用记】 local www = UnityEngine.WWW("http://www.baidu.com") coroutine.www(www) local s = tolua.tolstring(www.bytes) print(s:sub(1, 128)) print('Coroutine ended') end function TestCortinue() --启动协程 coroutine.start(CoFunc) end local coDelay = nil --等待协程方法 function Delay() local c = 1 while true do coroutine.wait(1) print("Count: "..c) c = c + 1 end end --开始等待协程 function StartDelay() coDelay = coroutine.start(Delay) end function StopDelay() --停止协程 coroutine.stop(coDelay) end
上面是ToLua作者调用自己重新封装的lua协程代码
-------------------------------------------------------------------------------- -- Copyright (c) 2015 - 2016 , 蒙占志(topameng) topameng@gmail.com -- All rights reserved. -- Use, modification and distribution are subject to the "MIT License" -------------------------------------------------------------------------------- local create = coroutine.create local running = coroutine.running local resume = coroutine.resume local yield = coroutine.yield local error = error local unpack = unpack local debug = debug local FrameTimer = FrameTimer local CoTimer = CoTimer local comap = {} local pool = {} setmetatable(comap, {__mode = "kv"}) function coroutine.start(f, ...) local co = create(f) if running() == nil then local flag, msg = resume(co, ...) if not flag then error(debug.traceback(co, msg)) end else local args = {...} local timer = nil local action = function() comap[co] = nil timer.func = nil local flag, msg = resume(co, unpack(args)) table.insert(pool, timer) if not flag then timer:Stop() error(debug.traceback(co, msg)) end end if #pool > 0 then timer = table.remove(pool) timer:Reset(action, 0, 1) else timer = FrameTimer.New(action, 0, 1) end comap[co] = timer timer:Start() end return co end --协程等待 function coroutine.wait(t, co, ...) local args = {...} co = co or running() local timer = nil local action = function() comap[co] = nil timer.func = nil local flag, msg = resume(co, unpack(args)) if not flag then timer:Stop() error(debug.traceback(co, msg)) return end end timer = CoTimer.New(action, t, 1) comap[co] = timer timer:Start() return yield() end --协程步骤 function coroutine.step(t, co, ...) local args = {...} co = co or running() local timer = nil local action = function() comap[co] = nil timer.func = nil local flag, msg = resume(co, unpack(args)) table.insert(pool, timer) if not flag then timer:Stop() error(debug.traceback(co, msg)) return end end if #pool > 0 then timer = table.remove(pool) timer:Reset(action, t or 1, 1) else timer = FrameTimer.New(action, t or 1, 1) end comap[co] = timer timer:Start() return yield() end function coroutine.www(www, co) co = co or running() local timer = nil local action = function() if not www.isDone then return end comap[co] = nil timer:Stop() timer.func = nil local flag, msg = resume(co) table.insert(pool, timer) if not flag then error(debug.traceback(co, msg)) return end end if #pool > 0 then timer = table.remove(pool) timer:Reset(action, 1, -1) else timer = FrameTimer.New(action, 1, -1) end comap[co] = timer timer:Start() return yield() end --协程暂停 function coroutine.stop(co) local timer = comap[co] if timer ~= nil then comap[co] = nil timer:Stop() end end
上述代码是ToLua作者自己封装协程的具体代码,此方法所有协程的代码都是放在lua语言里面,对性能消耗较小,建议使用此方法。如果阅读起来有难度,请先去Lua官网查看Lua中的协程是如何实现以及具体用法。官方文档地址
热更新_ToLua学习示例 05_LuaCoroutine
于 2023-04-03 10:08:24 首次发布