Lua文件加载

XLua只是提供Lua在Unity上运行,并没有提供热更行解决方案。

Lua文件加载

加载字符串

直接使用luaEnv.DoString()执行一个字符串,字符串必须符合Lua语法

但加载字符串这个方法不常用。

加载Lua文件

用Lua的require函数。

DoString("require '文件路径(基于Resources文件夹)'")

使用require默认从Resources下进行加载(放Resources下的lua文件得加上txt后缀)。

using UnityEngine;
using XLua;

public class Test : MonoBehaviour {
    // 创建一个Lua虚拟机
    LuaEnv luaEnv = null;

    void Start() {
        // 生成了这个虚拟机
        luaEnv = new LuaEnv();
        // 执行Lua语句
        luaEnv.DoString("print('Hello world')");
		// 执行byfile(Lua)文件
        luaEnv.DoString("require 'byfile' ");
    }
    // XLua只是提供Lua在Unity上运行,并没有提供热更行解决方案。

    void Update() {
        if (luaEnv != null)
            // 定时清理内存,luaEnv有自己的垃圾回收机制。
            luaEnv.Tick();
    }

    void OnDestroy() {
        // 手动释放掉
        luaEnv.Dispose();
    }
}

自定义加载器

使用require函数只能加载Resources文件下的文件,而Resources无法进行热更新。这时就需要用于自定义加载器。

资源热更新:

  • 服务器:制定打包工具、制定打包策略、将需要上传的资源上传到资源服务器。
  • 客户端:下载清单文件,对比hash值,一样的话读取本地,不一样下载AB包替换本地资源,并刷新hash值,提供资源管理器,根据资源路径找到对应的AB包,提取AB包中的资源。

逻辑热更新:

  • 逻辑热更新依赖于资源热更新,通过资源热更新更新对应的lua脚本内容,在LuaEnv调用之前,用户通过AddLoader添加自定义的逻辑,在自定义的逻辑中使用资源管理器调用AB包中的资源,就能够实现lua逻辑热更新。
using UnityEngine;
using System.Collections;
using XLua;

namespace Tutorial
{
    public class CustomLoader : MonoBehaviour
    {
        LuaEnv luaenv = null;
        // Use this for initialization
        void Start()
        {
            luaenv = new LuaEnv();
            luaenv.AddLoader((ref string filename) =>
            {
                if (filename == "InMemory")
                {
                    string script = "return {ccc = 9999}";
                    return System.Text.Encoding.UTF8.GetBytes(script);
                }
                return null;
            });
            luaenv.DoString("print('InMemory.ccc=', require('InMemory').ccc)");
        }

        // Update is called once per frame
        void Update()
        {
            if (luaenv != null)
            {
                luaenv.Tick();
            }
        }

        void OnDestroy()
        {
            luaenv.Dispose();
        }
    }
}

Lua调用C#脚本逻辑

// C#测试案例
using UnityEngine;
using XLua;

[LuaCallCSharp]
public class Weapon {
    public string name = "ailisi_dajian";
}

[LuaCallCSharp]
public class Hero {
    // 成员变量
    public string name = "ailisi";
    // 嵌套成员标量
    public Weapon weapon = new Weapon();

    public void cheng_yuan_fang_fa() {
        Debug.Log("C#:成员方法");
    }

    public static void jing_tai_fang_fa() {
        Debug.Log("C#:静态方法");
    }


    public string duo_fan_hui_zhi_fang_fa(ref string str) {
        return "return";
    }

}

// 防止在真机运行时lua不能调用C#
[LuaCallCSharp]
public class Warrior : Hero {
    public float Attack = 10;
}
// C#加载Lua文件
using UnityEngine;
using XLua;

public class DOLua : MonoBehaviour {
    public TextAsset lua;
    public LuaEnv luaEnv = null;
    void Start() {
        luaEnv = new LuaEnv();
        // 使用Xlua默认加载Lua脚本,需要放到Resources下
        luaEnv.DoString(lua.text);
    }

    void Update() {
        if (luaEnv != null)
            luaEnv.Tick();
    }

    void OnDestroy() {
        luaEnv.Dispose();
    }
}
-- Lua调用UnityAPI的时候每次都必须以CS开头,可以先在一个公共类中将频繁调用的类型声明出来
UnityEngine = CS.UnityEngine
GameObject = UnityEngine.GameObject
Transform = UnityEngine.Transform
Debug = UnityEngine.Debug
Hero = CS.Hero
Warrior = CS.Warrior
// Lua调用C#中的逻辑
-- 引入common公共类
require("common")

-- 创建一个GameObject
local obj = GameObject()
-- 改变GameObject名字
obj.name = "LuaCreateObj"

-- 实例化一个角色
local hero = Hero()

-- 输出角色名字
print(hero.name)
-- 输出角色武器名字
print(hero.weapon.name)
-- 使用:调用成员方法
hero:cheng_yuan_fang_fa()
-- 使用.调用静态方法
Hero.jing_tai_fang_fa()

local str ="str"
-- 多返回值成员方法
local a,b = hero:duo_fan_hui_zhi_fang_fa(str)
print(a,b)

-- 实例化一个战士
local warrior = Warrior()
-- 输出继承父类的成员变量
print(warrior.name)

XLua 配置

防止在真机情况下lua不能调用C#逻辑。

  • 打标签:用户自定义的类型可以进行打标签,系统api无法进行打标签(该方式方便,但在il2cpp下会增加不少代码,不建议使用)。

    [LuaCallCSharp]
    public class A{
    
    }
    
  • 静态列表:对于没法打标签的类型,这时可以在一个静态类里声明一个静态字段(下面是XLua框架中添加静态列表的脚本)。找到项目中ExampleGenConfig文件在里面添加指定的类型即可。

  • 动态列表

posted @   坞中客  阅读(464)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示