通过 util.cs_generator 可以用一个 function 模拟一个IEnumerator,在里头用coroutine.yield,就类似C#里头的yield return。
Lua对接C#协程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| local util = require 'xlua.util'
local gameobject = CS.UnityEngine.GameObject('Coroutine_Runner') CS.UnityEngine.Object.DontDestroyOnLoad(gameobject) local cs_coroutine_runner = gameobject:AddComponent(typeof(CS.XLuaTest.Coroutine_Runner))
return { start = function(...) return cs_coroutine_runner:StartCoroutine(util.cs_generator(...)) end; stop = function(coroutine) cs_coroutine_runner:StopCoroutine(coroutine) end }
|
util.cs_generator(…) 源码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| local function cs_generator(func, ...) local params = {...} local generator = setmetatable ({ w_func = function() func(unpack(params)) return move_end end }, generator_mt ) generator:Reset() return generator end
local generator_mt = { __index = { MoveNext = function(self) self.Current = self.co() if self.Current == move_end then self.Current = nil return false else return true end end; Reset = function(self) self.co = coroutine.wrap(self.w_func) end } }
|
Coroutine_Runner 源码分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| using UnityEngine; using XLua; using System.Collections.Generic; using System;
namespace XLuaTest { public class Coroutine_Runner : MonoBehaviour { }
public static class CoroutineConfig { [LuaCallCSharp] public static List<Type> LuaCallCSharp { get { return new List<Type>() { typeof(WaitForSeconds), typeof(WWW) }; } } } }
|
Lua 使用C#协程
1 2 3 4 5 6 7 8 9 10
| cs_coroutine.start ( function() print('start coroutine') print('start wait 5s') coroutine.yield(CS.UnityEngine.WaitForSeconds(5)) print('wait 5s down') end )
|