协程在unity中特别常用,在tolua中,我们也能在lua文本中实现协程调用;但是在demo范例中,除了协程调用,还有一些warp绑定一类的知识,可能学习起来会懵B;为了方便学习,我们可以对例子做出简单修改,使学生知识点更加串联。
打开ToLua/Examples/05_LuaCoroutine的TestCoroutine类文件,将类改外以下代码(去掉了绑定相关代码,指定为lua文件)。
using UnityEngine;
using System;
using System.Collections;
using LuaInterface;
//例子5和6展示的两套协同系统勿交叉使用,此为推荐方案
public class TestCoroutine : MonoBehaviour
{
public TextAsset luaFile = null;
private LuaState lua = null;
private LuaLooper looper = null;
void Awake()
{
#if UNITY_5 || UNITY_2017 || UNITY_2018
Application.logMessageReceived += ShowTips;
#else
Application.RegisterLogCallback(ShowTips);
#endif
//初始化状态
lua = new LuaState();
//调用状态开始方法
lua.Start();
looper = gameObject.AddComponent<LuaLooper>();//调用协程需要借助外部组件 不然等待不会执行
looper.luaState = lua;
//如果移动了ToLua目录,自己手动修复吧,只是例子就不做配置了
string fullPath = Application.dataPath + "\\ToLua/Examples/05_LuaCoroutine";
//添加lua文件路径
lua.AddSearchPath(fullPath);
lua.DoFile("TestLuaCoroutine.lua");
LuaFunction f = lua.GetFunction("TestCortinue");
f.Call();
f.Dispose();
f = null;
}
void OnApplicationQuit()
{
looper.Destroy();
lua.Dispose();
lua = null;
#if UNITY_5 || UNITY_2017 || UNITY_2018
Application.logMessageReceived -= ShowTips;
#else
Application.RegisterLogCallback(null);
#endif
}
string tips = null;
void ShowTips(string msg, string stackTrace, LogType type)
{
tips += msg;
tips += "\r\n";
}
void OnGUI()
{
GUI.Label(new Rect(Screen.width / 2 - 300, Screen.height / 2 - 200, 600, 400), tips);
if (GUI.Button(new Rect(50, 50, 120, 45), "Start Counter"))
{
tips = null;
LuaFunction func = lua.GetFunction("StartDelay");
func.Call();
func.Dispose();
}
else if (GUI.Button(new Rect(50, 150, 120, 45), "Stop Counter"))
{
LuaFunction func = lua.GetFunction("StopDelay");
func.Call();
func.Dispose();
}
else if (GUI.Button(new Rect(50, 250, 120, 45), "GC"))
{
lua.DoString("collectgarbage('collect')", "TestCoroutine.cs");
Resources.UnloadUnusedAssets();
}
}
}
其实如上代码,调用携程就和调用普通lua方法一样,只是借用了LuaLooper组件去实现协程的功能,如果不写
looper = gameObject.AddComponent();//调用协程需要借助外部组件 不然等待不会执行
looper.luaState = lua;
就会发现,携程方法会卡在wait的部分,不会往下执行。
其实也就是调用lua普通方法,在lua类里面,普通方法在去调用或停止对应的协程。
携程调用方式有两种,一种是作者封装好的,一种是类unity的,类unity的消耗较大,作者推荐为本方式调用协程。
由于去掉了lua与unity绑定,所以改为了加载外部lua文件,lua文件也是参考绑定的文件,只是去掉了unity相关的www加载代码,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))
coroutine.wait(0.1)
end
coroutine.wait(0.1)
print("current frameCount: "..Time.frameCount)
coroutine.step()
print("yield frameCount: "..Time.frameCount)
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