toLua[七] Examples 06_LuaCoroutine2分析

一.运行工程

本例展示Lua模拟Unity的Coroutine携程的第二种做法

二.C#代码分析

TestCoroutine2.CS

cs 复制代码
using UnityEngine;
using System.Collections;
using LuaInterface;

//两套协同勿交叉使用,类unity原生,大量使用效率低
public class TestCoroutine2 : LuaClient 
{
    string script =
    @"
        function CoExample()            
            WaitForSeconds(1)
            print('WaitForSeconds end time: '.. UnityEngine.Time.time)            
            WaitForFixedUpdate()
            print('WaitForFixedUpdate end frameCount: '..UnityEngine.Time.frameCount)
            WaitForEndOfFrame()
            print('WaitForEndOfFrame end frameCount: '..UnityEngine.Time.frameCount)
            Yield(null)
            print('yield null end frameCount: '..UnityEngine.Time.frameCount)
            Yield(0)
            print('yield(0) end frameCime: '..UnityEngine.Time.frameCount)
            local www = UnityEngine.WWW('http://www.baidu.com')
            Yield(www)
            print('yield(www) end time: '.. UnityEngine.Time.time)
            local s = tolua.tolstring(www.bytes)
            print(s:sub(1, 128))
            print('coroutine over')
        end

        function TestCo()            
            StartCoroutine(CoExample)                                   
        end

        local coDelay = nil

        function Delay()
	        local c = 1

	        while true do
		        WaitForSeconds(1) 
		        print('Count: '..c)
		        c = c + 1
	        end
        end

        function StartDelay()
	        coDelay = StartCoroutine(Delay)            
        end

        function StopDelay()
	        StopCoroutine(coDelay)
            coDelay = nil
        end
    ";

    protected override LuaFileUtils InitLoader()
    {
        return new LuaResLoader();
    }

    protected override void OnLoadFinished()
    {
        base.OnLoadFinished();

        luaState.DoString(script, "TestCoroutine2.cs");
        LuaFunction func = luaState.GetFunction("TestCo");
        func.Call();
        func.Dispose();
        func = null;
    }

    //屏蔽,例子不需要运行
    protected override void CallMain() { }

    bool beStart = false;
    string tips = null;

    void Start()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived += ShowTips;
#else
        Application.RegisterLogCallback(ShowTips);
#endif
    }

    void ShowTips(string msg, string stackTrace, LogType type)
    {
        tips += msg;
        tips += "\r\n";
    }

    new void OnApplicationQuit()
    {
#if UNITY_5 || UNITY_2017 || UNITY_2018
        Application.logMessageReceived -= ShowTips;
#else
        Application.RegisterLogCallback(null);
#endif
        base.OnApplicationQuit();
    }

    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"))
        {
            if (!beStart)
            {
                beStart = true;
                tips = "";
                LuaFunction func = luaState.GetFunction("StartDelay");
                func.Call();
                func.Dispose();
            }
        }
        else if (GUI.Button(new Rect(50, 150, 120, 45), "Stop Counter"))
        {
            if (beStart)
            {
                beStart = false;
                LuaFunction func = luaState.GetFunction("StopDelay");
                func.Call();
                func.Dispose();
            }
        }
    }
}

2.1 LuaClient.CS

首先看第六行TestCoroutine2 继承自 LuaClient

cs 复制代码
public class TestCoroutine2 : LuaClient

LuaClient的159-177行可以看出其初始化时创建了LuaState对象,故TestCoroutine2中没有LuaState对象的创建,可以直接使用父类的

cs 复制代码
    protected void Init()
    {        
        InitLoader();
        luaState = new LuaState();
        OpenLibs();
        luaState.LuaSetTop(0);
        Bind();        
        LoadLuaFiles();        
    }

    protected void Awake()
    {
        Instance = this;
        Init();

#if UNITY_5_4_OR_NEWER
        SceneManager.sceneLoaded += OnSceneLoaded;
#endif        
    }

再来看TestCoroutine2.CS的64-66行,执行Lua方法TestCo

cs 复制代码
        luaState.DoString(script, "TestCoroutine2.cs");
        LuaFunction func = luaState.GetFunction("TestCo");
        func.Call();

TestCoroutine2.CS的29-31行TestCo调用StartCoroutine

Lua 复制代码
        function TestCo()            
            StartCoroutine(CoExample)                                   
        end

2.2 LuaCoroutine.CS

全局搜索function StartCoroutine可以看到其定义位于文件LuaCoroutine.CS中

在DoString处加入断点,可以看到其由LuaClient的Awake中间接调用

三.Lua代码分析

从StartCoroutine的Lua实现来看,其用的是Lua语言自身的coroutine

Lua 复制代码
        function StartCoroutine(func)
            local co = coroutine.create(func)                       
            local flag, msg = coroutine.resume(co)

            if not flag then
                msg = debug.traceback(co, msg)
                error(msg)
            end

            return co
        end
相关推荐
Hody911 天前
【XR开发系列】2025 年 XR 开发入门,我该选择 Unity 还是 Unreal Engine?
unity·xr·虚幻
DvLee10241 天前
UnityGLTF 材质创建与赋值流程
unity·材质
HahaGiver6661 天前
从0到1做一个“字母拼词”Unity小游戏(含源码/GIF)- 字母拼词正确错误判断
unity·游戏引擎·游戏程序
一个小狼娃2 天前
Android集成Unity避坑指南
android·游戏·unity
极客柒2 天前
Unity 协程GC优化记录
java·unity·游戏引擎
黄思搏2 天前
Unity SpriteRenderer 进度条 Shader 实现
unity·游戏引擎
猫屋小鱼丸2 天前
手把手教你在unity中实现一个视觉小说系统(一)
unity
HahaGiver6663 天前
Unity与Android原生交互开发入门篇 - 打开Unity游戏的设置
android·unity·交互
@LYZY3 天前
Unity TextMeshPro 文本对齐方式详解
unity·游戏引擎·textmeshpro·tmp
在路上看风景3 天前
2.1 ShaderLab - 渲染状态
unity