xLua笔记(1)—Lua启动类

xLua笔记(1)—Lua启动类

前言

本笔记是为了学习用xlua写unity游戏而制作的笔记,作为自己加深对于知识的理解和记忆有感而发。如果错误,恳请各位大神回复纠正,谢谢

本教程是基于xLua的,至于xLua的教程这里我就不多说了,你可以上去xlua官网的github去下载。
根据xLua教程的建议,整个程序就一个DoString(“require ‘main’”),然后在main.lua加载其它脚本(类似lua脚本的命令行执行:lua main.lua)。本着这个原则,我设计了一个启动lua主脚本的类。
后面还会介绍怎么去在这个主lua类里去加载其他的lua代码。

lua启动类

1、lua启动代码
这个代码将会作为整个lua代码的启动类,加载其他脚本都通过这里(将来我会继续介绍怎么在这里加载其他lua脚本)
我把代码放在了Asset/LuaScripts文件夹下

--LuaGameEntry.lua
-- 定义为全局模块,整个lua程序的入口类

LuaGameEntry={};

local function EnterGame()
    print('enter game')
end

local function Start()
    print('start game')
    EnterGame()
end

LuaGameEntry.Start=Start;
LuaGameEntry.EnterGame=EnterGame;

return LuaGameEntry;

2、接着就到我们的xLua代码管理类
这个代码主要用来加载我们的启动lua脚本

using FileUtility;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;

public class XLuaManager : MonoSingleton<XLuaManager>
{
     //放置LuaScripts代码的文件夹名字
    public const string luaScriptsFolder = "LuaScripts";
    //lua代码的文件名
    const string luaGameEntryScript = "LuaGameEntry";
    private LuaEnv luaEnv = null;
    // Start is called before the first frame update
    void Start(){}

    protected override void Init()
    {
        base.Init();
        InitLuaEnv();
    }
    
    private void InitLuaEnv()
    {
        luaEnv = new LuaEnv();
        if (luaEnv != null)
        {
            luaEnv.AddLoader(CustomLoader);
        }
    }

    /// <summary>
    /// 回调中可以根据这个参数去加载指定文件
    /// 如果需要支持调试,需要把filepath修改为真实路径传出。
    /// 该回调返回值是一个byte数组,如果为空表示该loader找不到,否则则为lua文件的内容
    /// </summary>
    /// <param name="_filePath"></param>
    /// <returns></returns>
    public static byte[] CustomLoader(ref string _filePath)
    {
        string _scriptPath = string.Empty;
        _filePath = _filePath.Replace(".", "/") + ".lua";
        if (Application.platform == RuntimePlatform.WindowsEditor)
        {
            _scriptPath = Path.Combine(Application.dataPath, luaScriptsFolder);
            _scriptPath = Path.Combine(_scriptPath, _filePath);
            byte[] _bytes = FileManager.SafeReadAllBytes(_scriptPath);
            return _bytes;
        }

        return null;
    }

    /// <summary>
    /// lua脚本启动入口
    /// </summary>
    public void OnEntry()
    {
        if (luaEnv != null)
        {
            loadScript(luaGameEntryScript);
            DoString("LuaGameEntry.Start()");
        }
    }

    // Update is called once per frame
    void Update() { }

    private void loadScript(string _scriptName)
    {
        DoString(string.Format("require('{0}')", _scriptName));
    }

    /// <summary>
    /// 加载lua代码块
    /// </summary>
    /// <param name="_luaScript"></param>
    public void DoString(string _luaScript)
    {
        if (luaEnv != null)
        {
            try
            {
                luaEnv.DoString(_luaScript);
            }
            catch (System.Exception ex)
            {

                Debug.Log(ex.Message);
            }
        }
    }


}

1.InitEnv: 创建一个LuaEnv用于执行代码块,init方法在单例类里被调用了。(后面会贴上单例类)
2.CustomLoader: 这里会负责更改传进来的文件名,给文件名添加路径,加载正确的路径,从而通过C#加载lua文件里的内容。(当然,这里只是针对Unity编译器环境下的运行lua代码,后面还会有移动端的加载lua代码)

好了,到这里我们的代码基本就完成了。下面我们在unity下去调用,我们创建一个新C#脚本,首先调用StartUp()方法,让程序先创建好LuaEnv,然后再调用lua代码OnEntry。
OnEntry-loadScript-LuaGameEntry.Start()
在这里插入图片描述
我们就可以看到unity控制器里有我们在lua代码打印的信息了
在这里插入图片描述

相关链接:
xLua:https://github.com/Tencent/xLua
lua菜鸟教程:https://www.runoob.com/lua/lua-basic-syntax.html

PS:好久没写过笔记了,有点生疏,希望以后能加强一下自己的写作能力。

最后附上相关的其他代码
读取lua文件内容代码:

public static byte[] SafeReadAllBytes(string inFile)
        {
            try
            {
                if (string.IsNullOrEmpty(inFile))
                {
                    return null;
                }

                if (!File.Exists(inFile))
                {
                    return null;
                }

                File.SetAttributes(inFile, FileAttributes.Normal);
                return File.ReadAllBytes(inFile);
            }
            catch (System.Exception ex)
            {

                return null;
            }
        }

单例类

using UnityEngine;
using System.Collections;

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoSingleton<T>
{
    protected static T Instance = null;

    public static T GetInstance()
    {
        if (Instance == null)
        {
            Instance = FindObjectOfType<T>();
            if (FindObjectsOfType<T>().Length > 1)
            {
                return Instance;
            }

            if (Instance == null)
            {
                string instanceName = typeof(T).Name;
                GameObject instanceGameObject = GameObject.Find(instanceName);
                if (instanceGameObject == null)
                    instanceGameObject = new GameObject(instanceName);
                Instance = instanceGameObject.AddComponent<T>();
                DontDestroyOnLoad(instanceGameObject);
            }

        }

        return Instance;
    }

    private void Awake()
    {
        if(Instance==null)
        {
            Instance = this as T;
        }
        DontDestroyOnLoad(gameObject);
        Init();
    }

    /// <summary>
    /// 无实现函数,用于保证MonoSingleton在使用前已创建
    /// </summary>
    public void StartUp()
    {
        Debug.Log(string.Format("{0} is start up...", gameObject.name));
    }

    protected virtual void Init()
    {

    }

    protected virtual void OnDestroy()
    {
        Instance = null;
    }

}

发布了6 篇原创文章 · 获赞 3 · 访问量 6653

猜你喜欢

转载自blog.csdn.net/JoeyHuangzx/article/details/105036416