首页 > 其他分享 >【Unity】浅尝xlua热更新插件

【Unity】浅尝xlua热更新插件

时间:2022-09-29 23:13:05浏览次数:83  
标签:插件 lua -- 代码 浅尝 Lua Unity using main

前言

之前的学习中了解到了一些热更新的知识,本想系统地学习基于xLua的热更新框架,但时间紧迫,遂浅尝辄止。在此记录一下相关知识。

什么是热更新

从云端下载资源包,这些新资源包会被自动整合进现有软件中,达到动态更新软件的目的,而无需重新下载整个软件。

最主流的Unity热更新方式的有三种:

  1. XLua
  2. ILRuntime
  3. huatuo

前者是腾讯开源,网上教程很多、十分成熟、好评如潮,但要熟悉新语言lua;
中者用C#来作为热更语言,最大的优势是项目可以用同一个语言来进行开发;
后者是Unity全平台原生c#热更新方案,据说它特性完整、零成本、高性能、低内存、近乎完美。

xLua是什么

Tencent/xLua: xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc. (github.com)

Lua:Lua解释执行时,性能接近于native

xLua:xLua是Lua在C#环境( .net)的解决方案

xLua功能特性:

  1. 可以运行时把C#实现(方法,操作符,属性,事件等等)替换成lua实现;
  2. 出色的GC优化,自定义struct,枚举在Lua和C#间传递无C# gc alloc;
  3. 编辑器下无需生成代码,开发更轻量;
    详细说明见此处

如何向项目中引入xLua

github中下载ZIP文件后,解压,进入Assets文件夹,看到有如下四个文件。
image
把这四个文件直接复制进Unity项目中的Asset文件夹下,注意不要错放到Asset的子文件中。等待Unity编译完就可以了。

基于xLua的纯Lua开发框架的基本原则

  1. 游戏场景中不放任何游戏对象。避免冲突,用代码生成对象。

  2. 运行时仅有一个场景,不涉及场景切换。策划、美术、程序分离。

  3. 不手动向预制体上挂载代码。去编辑器化,便于维护代码。

  4. 以纯AssetsBundle代替Resources做资源管理。

    a:方便更新 :更新代码(lua->脚本代码ab包)+更新资源(AssetsBundle)

    b:方便打包:场景+场景依赖的资源;Resources文件夹下的所有资源打入安装包

  5. 制定一个纯Lua开发的组件化框架,方便编写业务逻辑与运算,尽可能减少Lua调用C#提升性能。

  6. 建立调试模式以加载Lua代码与资源:AssetsDatabase加载资源,供Editor模式下使用。

基本框架

目录结构

  1. AssetsPackage:用于存放所有游戏资源。
  2. Scenes:用于存放游戏场景。
  3. Scripts:用于存放框架性质的C#代码。
  4. LuaScripts:用于存放Lua代码。
  5. StreammingAssets:用于存放ab包。若不打空包,则将ab包放入该文件夹内,和安装包一起打包。
  6. Editor:用于扩展编辑器。

框架启动全流程

  1. GameLaunch单例
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class GameLaunch : MonoSingleton<GameLaunch>
{
    public void Awake()
    {
        //初始化游戏框架:声音管理,资源管理,网络管理等

    }

    IEnumerator CheckHotUpdate()
    {
        //热更新游戏资源+代码

        //end
        yield return null;
    }

    IEnumerator GameStart()
    {
        yield return this.StartCoroutine(this.CheckHotUpdate());

        //进入游戏,通过Lua虚拟机进入Lua逻辑代码
        Debug.Log("GameStart");
        //end
    }

    protected override void OnStart()
    {
        StartCoroutine(this.GameStart());
    }

}

独立化Lua脚本开发

  1. 内置Lua虚拟机。Managers->xLuaManager

  2. 将Lua代码脱离于C#代码,虚拟机加载我们的文本代码并执行。

    虚拟机装载执行第一个Lua脚本,main.lua

  3. 自定义一个Lua代码装载器(LuaScriptLoader),当我们请求装载代码时,到项目指定的路径下装载Lua代码。

  4. 装载方式:调试模式直接在LuaScripts下加载;发布模式LuaScripts->ab包->从ab包中加载Lua内容。

如下是代码示例。

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Unity.VisualScripting;
using UnityEditor;
using UnityEngine;
using XLua;

public class xLuaManager : MonoSingleton<xLuaManager>
{
    private static string luaScriptsFolder = "LuaScripts";
    private LuaEnv env = null;
    private bool isGameStarted = false;

    private void Awake()
    {
        this.InitLuaEnv();
    }

    public byte[] LuaScriptLoader(ref string filepath)
    {
        //Debug.Log("#" + filepath);
        string scriptPath = string.Empty;
        filepath = filepath.Replace(".", "/") + ".lua.txt";

# if UNITY_EDITOR//调试模式
        scriptPath = Path.Combine(Application.dataPath, luaScriptsFolder);
        scriptPath = Path.Combine(scriptPath, filepath);
        //byte[] data = GameUtility.SafeReadAllBytes(scriptPath);
        byte[] data = File.ReadAllBytes(scriptPath);
        return data;
#endif
        //发布模式

        return null;
    }

    private void InitLuaEnv()
    {
        this.env = new LuaEnv();
        this.env.AddLoader(this.LuaScriptLoader);
    }

    protected override void OnStart()
    {
        base.OnStart();

    }

    public void EnterGame()
    {
        //游戏正式开始
        this.isGameStarted = true;

        //进入游戏逻辑
        //Lua代码:print("helloworld!");
        this.env.DoString("require (\"main\")");
        this.env.DoString("main.init()");
    }

    private void Update()
    {
        if(this.isGameStarted)
            this.env.DoString("main.update()");
    }

    private void FixedUpdate()
    {
        if (this.isGameStarted)
            this.env.DoString("main.fixedUpdate()");
    }

    private void LateUpdate()
    {
        if (this.isGameStarted)
            this.env.DoString("main.lateUpdate()");
    }
}

main.lua.txt

--定义全局模块
main = {}

local GameApp = require("Game.GameApp")


local function init()
	--print("init")
	--初始化lua框架:自定义时间、网络、日志...
	--end

	--end进入游戏逻辑
	GameApp.EnterGame()
end

main.init = init

local function update()
	--每帧执行
	--print("update")
end

main.update = update

local function fixedUpdate()
	--每帧执行
	--print("fixedUpdate")
end

main.fixedUpdate = fixedUpdate

local function lateUpdate()
	--每帧执行
	--print("lateUpdate")
end

main.lateUpdate = lateUpdate

如何热更新代码与资源

注意:.lua无法打ab包,后缀必须改为.lua.byte才能打包。(有待考证,可能和框架有关)

利用assetbundle,将lua脚本打包为lua.assetsbundle,下载到本地;

加载lua脚本时,从ab包中加载最新的lua代码,加载完后执行。

和热更新其他资源的步骤是一样的。

参考资料

Tencent/xLua (github.com)
smilehao/xlua-framework (github.com)
Unity进阶教程:Xlua热更框架开发游戏【热更新视频教程】
ILRuntime.index

标签:插件,lua,--,代码,浅尝,Lua,Unity,using,main
From: https://www.cnblogs.com/OtusScops/p/16743325.html

相关文章

  • eclipse插件:打开选中文件所在的目录
    easyexplore是一个eclipse的小插件,它能直接打开选中文件所在的目录下载: 地址:​​http://sourceforge.net/projects/easystruts/files/​​,我下载的是org.sf.easyexplore_1.......
  • 常用Maven插件介绍
    exec-maven-plugin​​http://mojo.codehaus.org/exec-maven-plugin/​​exec-maven-plugin很好理解,顾名思义,它能让你运行任何本地的系统程序,在某些特定情况下,运行一个Maven......
  • jQuery插件开发模式
    jQuery插件开发模式软件开发过程中是需要一定的设计模式来指导开发的,有了模式,我们就能更好地组织我们的代码,并且从这些前人总结出来的模式中学到很多好的实践。根据《jQuery......
  • k8s消息队列-rabbiMQ集群(pod初始化安装消息延迟插件)
    一、方案:在k8s上部署rabbitMQ集群,pod初始化时安装消息延迟插件。二、部署参考rabbitMQ官方:https://www.rabbitmq.com/kubernetes/operator/operator-overview.html1、部......
  • 青龙面板-傻妞芝士插件
    傻妞-芝士插件(jd_cookie)用管理员给bot发送命令​​setjd_cookieenable_jd_cookietrue​​,并重启。这样芝士插件就开启了。青龙免部署上车,公众号内回复"青龙上车"​jdas......
  • WINFORM DEVEXPRESS插件常用功能总结
    前言DevExpress 控件的功能比较强大,是全球知名控件开发公司,对于开发 B/S 或 C/S 都非常出色,可以实现很炫且功能强大的效果。DevExpressWinform 常用控件是本人在......
  • 2022是元宇宙爆发年 最近Unity元宇宙外包和UE4元宇宙外包项目做的比较多 有需要欢迎联
    2022是元宇宙爆发年最近Unity元宇宙和UE4元宇宙相关项目做的比较多有需要欢迎联系我们......
  • 提高生产力的 IntelliJ 插件
    提高生产力的IntelliJ插件Photoby迪伦·费雷拉on不飞溅今天,我就如何增强开发人员的最爱之一—IntelliJIDE向您提出一些建议。我准备的插件是“通用”的,所以......
  • Maven插件
    前言Maven有以下三个标准的生命周期:clean:项目清理的处理default(或build):项目部署的处理site:项目站点文档创建的处理每个生命周期中都包含着一系列的阶段(phase)......
  • auo vue插件和html2word
    html2wordvuechrome插件......