xlua的简单使用

话不多说,先上代码

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

public class XLuaManager : MonoBehaviour
{
    LuaEnv luaEnv;
    public void OnInit()
    {
        luaEnv = new LuaEnv();
        //增加一个自定义loader
        luaEnv.AddLoader(CustomLoader);
        StartGame();
    }
    
    public void StartGame()
    {
        if (luaEnv != null)
        {
            LoadScript("GameMain");
            luaEnv.DoString("GameMain.Start()");
        }
    }
    
    void LoadScript(string scriptName)
    {
        SafeDoString(string.Format("require('{0}')", scriptName));
    }
    
    public void SafeDoString(string scriptContent)
    {
        if (luaEnv != null)
        {
            try
            {
                luaEnv.DoString(scriptContent);
            }
            catch (System.Exception ex)
            {
                string msg = string.Format("xLua exception : {0}\n {1}", ex.Message, ex.StackTrace);
                Debug.LogError(msg, null);
            }
        }
    }
    
    public byte[] CustomLoader(ref string filepath)
    {
        if (filepath == "emmy_core") return null; // EmmyLua调试Dll,走dll方式加载

        var loadPath = filepath.Replace(".", "/") + ".lua";
        var bytes = LoadBytes(loadPath);
        if (bytes == null) return null; // 加载文件失败,不修改filepath,尝试其它加载器
            
        //修改filepath 标记成功加载(相对路径用"/") 作为 chunkName 触发EmmyLua调试
        filepath = loadPath;
        return bytes;
    }
    
    public static byte[] LoadBytes(string loadPath)
    {
        // 读取时文件路径转为小写
        // 因为:
        // 1、Windows、Mac 默认不分大小写
        // 2、Git 默认不分大小写
        // 2、File 判定和读取也不区分大小写
        loadPath = loadPath.ToLower();
        var file = Path.Combine(LuaScriptsPath, loadPath);
        Debug.Log($"load lua file path:{file}");
        if (File.Exists(file))
            return File.ReadAllBytes(file);
        Debug.LogError($"Not Exist lua file: {file}");
        return null;
    }
    
    public static string LuaScriptsPath => Path.Combine(System.Environment.CurrentDirectory, "Assets/LuaScript");
}

lua代码如下


local UIManager = require("GameFramework/UIManager")
GameMain = {}

local function Start()
    print('<color=#fff000>Hello Xlua</color>')
    UIManager.onInit()
    UIManager.showUI("loginUI")

    require("GameFramework/Define")

    local uiRoot = GameObject.Find("uiRoot")

    local myObj = GameObject("hehe")
    print(uiRoot.name)

    print(GameUtils.GetAppVersion(),GameUtils.GetAssetsVersion())

    print(GameUtils.GetDeviceId())

    print(DataManager.getData("userName"),DataManager.getData("userLevel"))

    local myPlayer = ShowPlayer()
    myPlayer:Init()
end



GameMain.Start = Start

return GameMain
--这个是Define.lua
GameObject = CS.UnityEngine.GameObject
Transform = CS.UnityEngine.GameObject.Transfrom
GameUtils = CS.GameUtils
DataManager = CS.GameFramework.DataManager
ShowPlayer = CS.ShowPlayer

当然直接访问c#也是可以,属于反射的方式,比较耗性能

反射访问除了性能不佳之外,在il2cpp下还有可能因为代码剪裁而导致无法访问,后者可以通过下面介绍的ReflectionUse标签来避免。所以需要XLua.LuaCallCSharp

一个C#类型加了这个配置,xLua会生成这个类型的适配代码(包括构造该类型实例,访问其成员属性、方法,静态属性、方法),否则将会尝试用性能较低的反射方式来访问。

简单配置如下,创建一个脚本,放在unity工程的Editor下,这样就会生成对应wrap文件

using System;
using System.Collections;
using System.Collections.Generic;
using GameFramework;
using UnityEngine;
using XLua;

public static class GenConfig
{
    [CSObjectWrapEditor.GenPath]
    static string common_path = "Assets/XLua/Gen/";
    
    [LuaCallCSharp]
    public static List<Type> mymodule_lua_call_cs_list = new List<Type>()
    {
        typeof(GameObject),
        typeof(GameUtils),
        typeof(DataManager),
        typeof(ShowPlayer),
    };
}

对于c#的Struct还是少用,尽量封装静态方法

主要优化 减少gc + 减少lua与C#的交互。

  1. 为什么会产生gc?
    原因是boxing(装箱)和unboxing(拆箱)。Vector3(栈)转为object类型需要boxing(堆内存中),object转回Vector3需要unboxing,使用后释放该object引用,这个堆内存被gc检测到已经没引用,释放该堆内存,产生一个gc内存。

  2. 如何优化gc?
    值拷贝

简单的解决办法,可以采用tolua已经写好的代码,或许有问题或者有优化空间,自行处理

最后还有点疑问,如何在lua创建Button类,直接创建一个Button,大致就是c#中写框架,lua中写业务逻辑,看了一些相关的帖子,可以参考xlua-framework,git可以找到,但是要自己写一套该如何下手呢,有知道的大神请指教一下,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值