xLua游戏中的热更新(基于Unity2018)

什么是热更新

热:就是刚出炉

简单来说就是当游戏某个功能出现bug,或者修改了某个功能,或者增加了某个功能的时候,我们不需要重新下载安装安装包,就可以更新游戏内容。

 

热更新的好处:不用浪费流量重新下载,不用通过商店审核更加快速,不用重新安装玩家可以更快体验到更新的内容

 

目前比较受欢迎的热更新方案:uLua tolua xLua

热更新方案

这些热更新方案都是基于Lua语言的,也可以叫做lua插件(可以运行lua,并实现了luaC#交互的插件)。

所以本质上这些热更新方案就是一个lua插件,可以运行lua,并实现了luaC#交互的插件。

 

1,(luainterface cs2lua tolua-->ulua(不再维护,转到主要维护tolua)

2tolua(基于tolua开发了luaframework

3slua代码质量好,性能比tolua

4C#lightLSharp同一个作者(商用比较少)

xLua

  xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,因其良好性能、易用性、扩展性而广受好评。现在,腾讯已经将xLua开源到GitHub。

  2016年12月末,xLua刚刚实现新的突破:全平台支持用Lua修复C#代码bug。

  目前Unity下的Lua热更新方案大多都是要求要热更新的部分一开始就要用Lua语言实现,不足之处在于:

1、接入成本高,有的项目已经用C#写完了,这时要接入需要把需要热更的地方用Lua重新实现;

2、即使一开始就接入了,也存在同时用两种语言开发难度较大的问题;

3、Lua性能不如C#;

  xLua热补丁技术支持在运行时把一个C#实现(函数,操作符,属性,事件,或者整个类)替换成Lua实现,意味着你可以:

1、平时用C#开发;

2、运行也是C#,性能秒杀Lua;

3、有bug的地方下发个Lua脚本fix了,下次整体更新时可以把Lua的实现换回正确的C#实现,更新时甚至可以做到不重启游戏;

  这个新特性iOS,Android,Window,Mac都测试通过了,目前在做一些易用性优化。

什么是xLua

xLua为Unity、 .Net、 Mono等C#环境增加Lua脚本编程的能力,借助xLua,这些Lua代码可以方便的和C#相互调用。

 

创建工程导入xLua插件

通过xlua插件运行lua程序

创建一个Helloworld脚本,用来执行lua的输出语句

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

public class Helloworld01 : MonoBehaviour
{
    private LuaEnv luaEnv;
    void Start()
    {
        luaEnv = new LuaEnv();//创建lua运行环境
        luaEnv.DoString("print('Hello world')");//在()里面写lua语句
    }

    private void OnDestroy()
    {
        luaEnv.Dispose();//释放lua环境
    }
}

在lua中调用C#中的方法

另外一种输出方式,在lua中调用C#中的方法

luaEnv.DoString("CS.UnityEngine.Debug.Log('Hello world')");

加载运行lua源文件

首先创建一个helloworld.lua.txt的文件,必须为txt格式

然后创建一个Helloworld02的脚本进行加载

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

public class Helloworld02 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
       TextAsset ta = Resources.Load<TextAsset>("helloworld.lua");//helloworld.lua.txt
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString(ta.text);
        luaEnv.Dispose();
    }
}

通过内置的loader加载lua源文件

        luaEnv.DoString("require 'helloworld'");//loader进行加载helloworld.lua.txt  从Resources文件中进行加载

添加自定义的Loader方法

两只情况:一种是添加了一个自定义的Loader返回null并且DoString里面添加的是一个不存在的lua文件。它会返回错误。

    void Start()
    {
        LuaEnv env = new LuaEnv();
        env.AddLoader(MyLoader);
        env.DoString("require 'xxxxx'");
        env.Dispose();
           
    }

    private byte[] MyLoader(ref string filePath)
    {
        print(filePath);
        return null;
    }

另一种是添加了一个自定义的Loader返回lua语句的二进制并且DoString里面添加的是一个不存在的lua文件。它会执行自定义的Loader的输出。

    void Start()
    {
        LuaEnv env = new LuaEnv();
        env.AddLoader(MyLoader);
        env.DoString("require 'xxxxx'");
        env.Dispose();
           
    }

    private byte[] MyLoader(ref string filePath)
    {
        //print(filePath);
        string s = "print(123)";
        return System.Text.Encoding.UTF8.GetBytes(s);
    }

通过自定义Loader加载指定目录的Lua脚本

    void Start()
    {
        LuaEnv env = new LuaEnv();
        env.AddLoader(MyLoader);
        env.DoString("require 'test007'");
        env.Dispose();
           
    }

    private byte[] MyLoader(ref string filePath)
    {
        string adsPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt";
        return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(adsPath));
    }

C#访问Lua之访问Lua中的全局变量

    void Start()
    {
        LuaEnv env = new LuaEnv();
        env.DoString("require 'CSharpCallLua'");//调用完才能取得里面的变量
        int a = env.Global.Get<int>("a");//获取lua里面的全局变量a
        print(a);
        string str = env.Global.Get<string>("str");//获取lua里面的全局变量str
        print(str);
        bool isDie = env.Global.Get<bool>("isDie");//获取lua里面的全局变量isDie
        print(isDie);
        env.Dispose();
    }

C#访问Lua之访问Lua中的table(映射到class)

    void Start()
    {
        LuaEnv env = new LuaEnv();
        env.DoString("require 'CSharpCallLua'");//调用完才能取得里面的变量
        Person p = env.Global.Get<Person>("person");
        print(p.name + "-" + p.age);
        p.name = "Akimoto";
        env.DoString("print(person.name)");
        env.Dispose();
    }

    class Person
    {
        public string name;
        public int age;
    }

这种方式的访问,修改p的值不会影响到lua里面的表的属性

C#访问Lua之访问Lua中的table(映射到interface)

    [CSharpCallLua]
    public interface IPerson
    {
        string name { get; set; }
        int age { get; set; }
    }

        IPerson p = env.Global.Get<IPerson>("person");
        print(p.name);

映射到interface修改p中的属性,lua中的原table也会发生变化

C#访问Lua之通过Dictionary或者List

        //通过DIctionary,List
        //Dictionary<string, object> dict = env.Global.Get<Dictionary<string, object>>("person");
        //foreach (string key in dict.Keys)
        //{
        //    print(key + " " + dict[key]);
        //}

        List<object> list = env.Global.Get<List<object>>("person");
        foreach (object o in list)
        {
            print(o);
        }

C#访问Lua之通过LuaTable访问table

        //通过LuaTable类 比较慢
        LuaTable luaTable = env.Global.Get<LuaTable>("person");
        print(luaTable.Get<string>("name"));
        print(luaTable.Get<int>("age"));

C#访问Lua中的全局function(第一种方式)

使用委托来获取

        //访问lua中的全局函数
        //Action act1 = env.Global.Get<Action>("add");
        //act1();
        Add add = env.Global.Get<Add>("add");
        add(1, 2);
        env.Dispose();
    }

    [CSharpCallLua]
    delegate void Add(int a, int b);

通过LuaFunction访问Lua中的全局函数

        //使用LuaFunction来映射全局函数
        LuaFunction func = env.Global.Get<LuaFunction>("add");
        func.Call(1, 2);
        env.Dispose();

在Lua中new C#对象(创建游戏物体)

创建一个lua文件

CS.UnityEngine.GameObject()

创建一个C#脚本

    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();

        luaEnv.DoString("require 'LuaCallCSharp'");
    }

Lua访问C#静态属性和方法

修改lua代码

print(CS.UnityEngine.Time.deltaTime)

CS.UnityEngine.Time.timeScale = 0.5

local gameObject = CS.UnityEngine.GameObject

local camera = gameObject.Find("Main Camera")

camera.name = "update by lua"

Lua访问C#成员属性和方法

local cameraCom = camera.GetComponent(camera,"Camera")
gameObject.Destroy(cameraCom)

 

  • 23
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Unity XLua 商业级游戏源码是指使用Unity引擎和XLua语言进行开发的高质量、专业水准的游戏源代码。 首先,Unity是世界上最流行和强大的游戏引擎之一,广泛用于创建各种类型的游戏,包括PC、手机、虚拟现实和增强现实游戏。它提供了丰富的工具和功能,使开发者可以轻松创建出错综复杂和令人印象深刻的游戏Unity的跨平台特性也使得游戏可以在不同的设备上运行。 而XLua是一种基于Lua语言的脚本编程框架,它可以与Unity引擎完美集成,为开发者提供了更灵活、高效的游戏开发方式。XLua具有良好的性能和扩展性,可以轻松地将Lua脚本与C#代码结合起来,发挥出各自的优势。 商业级游戏源码意味着这些源代码是由具有丰富游戏开发经验的专业开发团队编写的。他们经过精心设计和优化,代码结构清晰,易于理解和维护。商业级游戏源码通常包含了各种常见的游戏开发功能,例如角色控制、物体碰撞、动画系统、UI界面、游戏关卡设计等。这些源码可以作为学习游戏开发的参考,也可以用于商业游戏项目快速搭建和开发。 总结来说,Unity XLua 商业级游戏源码是一种高质量和专业水准的游戏源代码,它利用Unity引擎和XLua语言的强大功能,为游戏开发者提供了高效、灵活的开发方式,可以用于学习游戏开发和商业游戏项目的开发。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值