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
相关推荐
寂寞的船1 天前
【Unity知识速递】第8期 IL2CPP 托管堆内存碎片与原生堆交互机制深度解析
unity·游戏引擎·交互
寂寞的船2 天前
【Unity知识速递】第5期 Unity 6.2 深度解析:AI Assistant 登场,World Space UI 与 Sentis 全面升级
人工智能·ui·unity
寂寞的船2 天前
【Unity知识速递】第4期 MCP for Unity:用 AI 自然语言控制编辑器
人工智能·unity·编辑器
淡海水2 天前
09-04-内存-Unity原生对象生命周期
unity·c#·游戏引擎·gc
寂寞的船2 天前
【Unity知识速递】第6期 URP性能优化完全指南:从内存到GPU的三维调优
unity·性能优化·编辑器
寂寞的船2 天前
【Unity Bug挑战】第10期 SerializeReference 内存泄漏之谜
unity·c#·游戏引擎·bug
tealcwu4 天前
【Unity基础】为什么游戏需要物理按键映射?从 Unity Input Manager 到跨引擎输入设计
java·游戏·unity
tealcwu5 天前
【Unity高级】Unity URP:构建同时支持 2D 与 3D 场景的项目完全指南
3d·unity·游戏引擎
淡海水5 天前
10-01-互操作-C#与C++边界的内存管理
unity·c#·游戏引擎·.netcore·gc
小小数媒成员5 天前
UGUI原理(一)
开发语言·游戏·unity·游戏引擎