简介

  在基于lua进行热更新的项目中,我们通常会通过luaBehaviour来让lua文件模拟MonoBehaviour,可以让lua文件拥有一些MonoBehaviour的生命周期,如Enable、Disable、Update。

  同时可以注入一些UnityEngine.Object。在lua中方便的调用Unity中的对象。方便开发者进行开发。

  本文进行介绍的luaBehaviour就是基于这个思路设计的,除了上面提到的特性之外还通过Json支持了更多类型的注入,Editor界面更人性化的展示,整个开发过程更接近MonoBehaviour的开发体验。

使用

1.新建继承LuaBehaviour的lua文件,通过AddDefineList添加需要序列化的信息。



2.直接把这个lua文件拖到CS中的LuaBehaviour上即可。





  接下来可以像MonoBehaviour一样对数据进行编辑了。

实现

脚本的序列化

  luaBehaviour在使用的时候一般是通过记录名字或路径的方式来序列化lua文件的的。打包后通过这个路径从AssetBundle中进行lua文件的加载(这个是lua脚本热更新常用的策略,在这边就不多说了)。

  这里还是通过路径来记录lua文件,但是不需要手动输入,而是通过直接拖动的方式间接记录lua文件路径。

注入的方式

  不通过C#侧定义注册信息,而是通过在Lua中先定义好要注册的类型和名称(更符合MonoBehaviour的开发姿势)。开发时,Editor读取lua中定义的类型和名称信息,展示在Inspector中,供开发者编辑。

  在运行时再将序列化的数据注入到lua实例中。

序列化的实现

UnityEngine.Object类型对象的序列化

  这种类型没啥特别的,在LuaBehaviour脚本中定义一个记录key和UnityEngine.Object的List即可。

其他类型的序列化

  非UnityEngine.Object类型就没有一个统一的格式,无法通过一个列表简单的进行记录。但是我们查看Prefab的实例可以发现,Prefab序列化的数据其实和Json很像。对在MonoBehaviour中定义的各个字段的序列化姿势也和Json很像。



  所以这里考虑使用Json来序列化非UnityEngine.Object类型的对象。刚好Unity由提供了一套简单高效的Json工具JsonUtility。JsonUtility内部就是通过Unity serializer实现的,所以稳定性很有保证。

  但是JsonUtility有个缺点,只能序列化一部分类型,不能序列化如Int、List这种类型。

  为了解决这个问题。这里在序列化的时候通过泛型为每个类型生成一个Wrap类型。即可通用的实现各种类型的序列化。

注入的实现

UnityEngine.Object类型对象的注入

  也没啥好说的,直接根据key向Lua实例中Set即可。

其他类型的注入

  先实例化为Wrap对象,然后再取出其中的需要注入的对象,Set到Lua对象中即可。

Inspector界面中的展示

UnityEngine.Object类型对象的展示

  UnityEngine.Object类型统一使用EditorGUILayout.ObjectField绘制即可。

其他类型的展示

  因为没有找到一个通用的可以表现所有对象的绘制方式,所以这里也做了一个转换。先通过Emit生成一个继承自ScriptableObject的类(因为ScriptableObject是UntiyEngine.Object,所以可以使用SerializedObject来绘制。同时可以直接通过ScriptableObject.CreateInstance进行实例的创建)。把需要绘制的对象放到这个类里面,然后通过EditorGUILayout.PropertyField绘制即可。

Enable、Update等函数的调用

  这里把Update、FixedUpdate等高频或者很少使用的函数拆分出去,只有在Lua中定义了这些函数,才添加对应的Assistant脚本对这些函数进行调用。



  Enable、Disable、Destroy这三个常用函数,就直接放在LuaBehaviour脚本中进行调用。

Tips

  1. 这篇文章只起到大致思路和关键点的说明,具体细节可以直接看代码,代码比较少也比较清晰。
  2. 通过Wrap的方式序列化各种对象的方式其实也可以考虑用到一些用户数据在客户端的持久化。
  3. 因为这边主要展示LuaBehanviour的功能,所以AssetBundle的生成和从AssetBundle中加载lua文件都写得很临时,仅作展示用。
  4. 打包测试之前要用AssetBundles->Build AssetBundle For Lua生成一下bundle。

项目链接:https://github.com/blueberryzzz/LuaBehaviour

Xlua中LuaBehaviour的实现的更多相关文章

  1. xLua中导出Dotween

    前言 在xlua的lua脚本中使用dotween,官方的文档中有提到可以导出,但未介绍详细的步骤,相信比较多的朋友有需要,刚好项目中也在使用xlua和dotween,所以做个笔记. 基础知识: xLu ...

  2. 【第二篇】xLua中lua加载方式

     xLua中lua文件加载方式 1. 直接执行字符串方式 LuaEnv luaenv = new LuaEnv(); luaenv.DoString("CS.UnityEngine.Debu ...

  3. xLua中C#调用Lua

    C#调用Lua 一.前提 这里使用的是XLua框架,需要提前配置xlua,设置加载器路径: 可以参考之前的Blog:<xlua入门基础>: 二.C#调用Lua全局变量 lua中所有的全局变 ...

  4. xLua中Lua调用C#

    xLua中Lua调用C# 1.前提 这里使用的是XLua框架,需要提前配置xlua,设置加载器路径: 可以参考之前的Blog:<xlua入门基础>: //调用段,所有的lua代码都写在Lu ...

  5. xlua中lua对象到c#对象的转型

    lua中的类型 基础类型 #define LUA_TNIL 0 #define LUA_TBOOLEAN 1 #define LUA_TLIGHTUSERDATA 2 #define LUA_TNUM ...

  6. 现学现卖】IntelliJ+EmmyLua 开发调试Unity中Xlua

    http://blog.csdn.net/u010019717/article/details/77510066?ref=myread http://blog.csdn.NET/u010019717 ...

  7. unity+xlua开发中的问题笔记

    转载请标明出处:http://www.cnblogs.com/zblade/ 一.概述 整理遇到的一些较难处理的bug,总结相关经验 二.主要问题 2.1 material类型的依赖修改 对于mate ...

  8. xlua 实现协程替换Unity中的协程

    C#中的协程: IEnumerator ShowSpiritInfo() { UIMessageMgr.ShowMsgWait(true); DestroyUIModelInfo(); bool is ...

  9. xlua怎么样hotfix C#中的重写方法???

    问题的来源之这样的: 线上项目遇到一个问题,就是子类 override 了父类的一个 virtual 方法,并且调用到了父类里面的 virtual 方法.现在子类  override 的方法里有一些错 ...

随机推荐

  1. 【Python】抽象工厂模式

    前言 接着上一篇的故事工厂模式继续,手机要出厂,显然光一个手机肯定是不行的,还需要包装盒.充电器等等东西.我们按照上一篇提到的工厂模式,去建立新的工厂是一点都没有问题的.但是思考一下这样子做会带来的问 ...

  2. 没错,用三方 Github 做授权登录就是这么简单!(OAuth2.0实战)

    本文收录在个人博客:www.chengxy-nds.top,技术资源共享. 上一篇<OAuth2.0 的四种授权方式>文末说过,后续要来一波OAuth2.0实战,耽误了几天今儿终于补上了. ...

  3. TortoiseGit 解决冲突的两种方法

    一.冲突发生原因: 用户A 有新提交 用户B 没有pull, 写新代码 ,pull , 提示有冲突   Solution: 1: stash save(把自己的代码隐藏存起来) -> 重新pul ...

  4. oracle添加配置多个端口监听

    原来配置:listener.ora文件如下: LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOS ...

  5. 多云架构下,JAVA微服务技术选型实例解析

    [摘要] 本文介绍了基于开源自建和适配云厂商开发框架两种构建多云架构的思路,以及这些思路的优缺点. 微服务生态 微服务生态本质上是一种微服务架构模式的实现,包括微服务开发SDK,以及微服务基础设施. ...

  6. 关联吸纳的remote首次push报错rejected

    F:\abb-iot\DmsAPI\DmsAPI (master -> origin) λ git push --set-upstream github master To github.com ...

  7. jstree 权限树 简单教程

    第一 :引用.略过 第二 : 初始化: //初始化加载 window.onload = function () { //获取树 信息 todo var result=[{ "id" ...

  8. redis启动报错:The Windows version of Redis allocates a memory mapped heap for sharing with

    windows系统下通过cmd命令:redis-server.exe redis.windows.conf 启动redis报错,控制台报错如下: The Windows version of Redi ...

  9. 深入理解Spring AOP 1.0

    本文相关代码(来自官方源码spring-test模块)请参见spring-demysify org.springframework.mylearntest包下. 统称能够实现AOP的语言为AOL,即( ...

  10. Numpy数组排序

    import numpy as np x = np.array([1,4,5,2]) # array([1, 4, 5, 2]) # 返回排序后元素的原下标 np.argsort(x) # array ...