SimpleFramework

思考并回答以下问题:

tolua,从高效率、稳定性、代码质量等方面都提升N倍,重写的引擎:代码简洁,逻辑清晰明了,是代码优雅+效率之神完美化身。

ulua:支持反射 + wrap方式。众多人维护,原作者是老外,蒙哥给它做了cstolua,让它变得更快。

SimpeFramework_NGUI/UGUI:基于ulua的框架,给大家一个ulua如何使用演示。

tolua:不支持反射(暂时) + wrap方式。虽然ulua之前是最快的,但tolua#效率比ulua还要高。

LuaFramework_NGUI/UGUI:基于tolua的框架,新的引擎新的框架。
(1)跟SimpeFramework最大的区别是,自身支持LuaBundleMode,可以在SimpeFramework时代很麻烦的将lua文件如何打包进assetbundle的情况,自身支持了,而且支持混合打包,也就是bytecode编码完后,再打入AssetBundle。你需要做的就是设置下开关。
(2)重新写的ResourceManager,之前SimpeFramework用的Unity5刚出来的时候的AssetBundle加载管理方式,我们在使用过程中,结合lua,发现很多地方太过复杂,而且逻辑不清晰,因此,我重写了ResourceManager,你们也可以更加方便修改其代码。

SimpleFramework_UGUI已经停止维护了。最新版本是2016年1月发布的v0.4.1。作者推荐使用基于tolua的LuaFramework,是基于SimpleFramework + tolua #基础上,重新构造的新框架。

SimpleFramework_UGUI

uLua

1、ULua 集成开发环境叫做:SimpleFramework
2、SimpleFramework 分为两个版本:
NGUI 版和 UGUI 版,区别是 NGUI 版本的框架资源中含有 NGUI 这个插件。
3、SimpleFramework 是一个 Unity3D的项目工程,可以用 Unity 直接打开这个项目工程
4、.SimpleFramework 和ULua的关系
SimpleFramework > ULua > Lua
ULua 是对原生 Lua 环境进行了一次封装,用于满足 Unity 环境下的热更新需求。为了更方便的使用,于是又对 ULua 进行二次封装,封装成了SimpleFramework框架

资源结构目录

五个根文件夹(UGUI版本)
1、Examples:SimpleFramework 热更新案例;
2、Lua:SimpleFramework 框架自带的 Lua 源码文件;
3、Plugins:uLua 运行所依赖的底层库文件,不需要碰;
4、Scripts:SimpleFramework 自带的 C#脚本文件;
5、uLua:uLua 全部代码。

备注:Lua 文件夹结构分析
SimpleFramework 框架自带的 Lua 源码文件。
1、3rd:第三方的 Lua 脚本插件;
2、Common:公共 Lua 文件目录;
3、Controller:控制器目录;
4、Logic:管理器目录;
5、System:cstolua 的系统目录;
6、View:视图层目录。

备注:

这些文件夹中的 Lua 脚本如果直接使用 SciTE 打开,脚本中的中文注释是乱码状态,可以使用 NotePad++打开,中文就不会出现乱码。
我们自己写的 Lua 脚本也是存放在 Lua 文件夹中。

框架自带菜单命令

Lua 菜单:uLua 环境相关处理命令
Game 菜单:用于打包不同平台的 AssetBundle 文件

框架使用步骤

1、生成 Wrap 文件(必备操作)

Wrap 文件介绍:
该文件夹下的脚本对 Unity 内常用组件脚本的二次包装,Lua 环境运行后,会把这些 Wrap 文件加载到 Lua 运行环境(Lua 虚拟机)中,最终的效果就是:
Lua 调用 Wrap 文件,Wrap 文件调用 C#,来实现 Lua 调用 C#。
生成 Wrap 文件的目的是为了提高 Lua 的执行效率。

2、生成不同平台的AssetBundle 资源(必备操作)

ULua基础之C#与Lua交互

uLua 文件夹结构

文件夹结构
Core:uLua 核心;
Docs:uLua 文档,其实就是 LuaInterface 的 PDF 使用文档;
Editor:uLua 编辑器扩展;
Examples:uLua 自带演示案例;
Source:cstolua 核心目录。

C#代码中执行 Lua 代码

1
2

`

Lua代码中操作Unity的类

实现方式

两种方式

1.反射/原生方式

1、这种方式就是我们之前在 VS 环境下演示的方式;
2、luanet 已经被封装到了 LuaInterface 命名空间内,所以我们可以在 Lua代码中直接使用 luanet 这个对象;
3、在 Lua 环境内操作 C#中的类来创建对象,不要写 new 关键字
4、在 Lua 环境内操作 C#中的类创建对象,访问对象中的方法使用冒号(:)
5、这种“反射方式”在项目开发中并不常用,偶尔会用,真正大量使用的是下方的 Wrap 方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using LuaInterface;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Init : MonoBehaviour {

// Use this for initialization
void Start ()
{
LuaState lua = new LuaState();
lua.DoString(@"luanet.load_assembly('UnityEngine')
GameObject = luanet.import_type('UnityEngine.GameObject')
BoxCollider = luanet.import_type('UnityEngine.BoxCollider');
local obj = GameObject('EmptyObj')
obj:AddComponent(luanet.ctype(BoxCollider)) -- .isTrigger = true
obj:GetComponent(luanet.ctype(BoxCollider)).isTrigger = true
");
}
}

2.Wrap 方式(推荐使用)

1、这种是在uLua开发过程中最常用的方式,基本都是使用这种方式;
2、Wrap方式实现Lua调用C#,依赖的是之前生成的LuaWrap文件;[也就是我们通过菜单自动生成到uLua\Source\LuaWrap下的脚本文件]
3、当使用Wrap方式时,运行Lua代码需要使用LuaScriptMgr;

注意:记得把AppConst里面的DebugMode设置为true,表示正处于调试模式,否则报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using LuaInterface;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Init : MonoBehaviour {

// Use this for initialization
void Start ()
{
LuaScriptMgr lua = new LuaScriptMgr();
lua.Start();
lua.DoString(@"luanet.load_assembly('UnityEngine')
GameObject = UnityEngine.GameObject
BoxCollider = UnityEngine.BoxCollider
local obj = GameObject('EmptyObj')
obj:AddComponent(BoxCollider.GetClassType())
");
}
}

包装新的 Wrap 脚本

当我们用 Lua 的 Wrap 方式访问 Unity 中的组件脚本,或者自己写的脚本的使用,如果这些脚本没有自动生成“xxxxWrap”,项目运行后,就会报错。
演示:比如 Animator 脚本,就没有默认生成 Wrap 格式的文件。

遇到这种情况,我们就需要往框架的 Wrap 生成器中添加我们要处理的新的类。步骤如下:
①找到 uLua\Editor\WrapFile.cs 打开该脚本,

使用该格式进行添加:_GT(typeof(类名)) ;
②Lua—>Clear LuaBinder File + Wrap File 清空原有的 Wrap 文件;

③Lua—>Gen Lua Wrap Files 重新生成 Wrap 文件;这样就能看的新增的 Wrap 脚本文件了。

案例

《使用 Lua 语言循环生成墙壁》
流程:C#调用Lua,Lua调用C#
推荐先写出C#版本,再转换成lua版本,这样能减低lua书写难度
1、先使用 C#生成一个砖块,然后转换成 Lua 语言版本;
2、再使用 C#循环生成墙壁,然后再转换成 Lua 语言版本。
备注:
Lua 语言是“弱类型语言”,意味着我们在 Lua 语言中无法使用

Lua 语言内操作 C#中的对象的属性使用“.”来调出;

实例化出来的对象,调用对象自身的方法用“:”;而类调用类中的静态方法,还是使用“.”。

说白了,访问属性都用一个点,访问方法都用两个点(特例,调用静态方法用一个点)

LuaCreateWall.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LuaCreateWall : MonoBehaviour
{
void Start()
{
//CreateOneCube();

LuaScriptMgr lua = new LuaScriptMgr();
lua.Start();
// lua.DoString(luaCreateCube);
lua.DoString(luaCreateWall);
}

// 单个Cube
private void CreateOneCube()
{
GameObject cube = Resources.Load<GameObject>("Cube");
GameObject.Instantiate(cube);
}

private string luaCreateCube = @"
luanet.load_assembly('UnityEngine')
Resources = UnityEngine.Resources
GameObject = UnityEngine.GameObject
local cube = Resources.Load('Cube')
local player = GameObject.Instantiate(cube)
player.name = 'MyCube'
";

// 墙
private void CreateCubeWall()
{
GameObject cube = Resources.Load<GameObject>("Cube");

for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
GameObject.Instantiate(cube, new Vector3(i, j, 0), Quaternion.identity);
}
}
}

private string luaCreateWall = @"
luanet.load_assembly('UnityEngine')
Resources = UnityEngine.Resources
GameObject = UnityEngine.GameObject
Vector3 = UnityEngine.Vector3
Quaternion = UnityEngine.Quaternion

local cube = Resources.Load('Cube')

for i = 0,9,1 do
for j = 0,9, 1 do
local player = GameObject.Instantiate(cube, Vector3(i,j,0), Quaternion.identity)
player.name = i..j
end
end
";
}

需要在WrapFile.cs里添加

1
2
3
_GT(typeof(Resources)),
_GT(typeof(Vector3)),
_GT(typeof(Quaternion)),

注意:
在正式开发过程中,为了实现热更新,Lua 代码需要存放于独立的 Lua 脚本文件中。我们编写的所有的 Lua 脚本文件,都需要存放在 SimpleFramework 框架项目的根目录下的 Lua 文件夹内。
因为放到这个目录下,在使用菜单命令生成 AB 包的时候,会把该文件夹下所有的Lua脚本一起拷贝到StreamingAssets目录下,为下一步热更新做准备

相关设置

在 SimpleFramework 这个框架项目中,有一个配置文件 AppConst.cs,该文件所在位置是:Scripts/ConstDefine/AppConst.cs。
在这个文件中配置了很多项目开发过程中,需要使用到的“公共常量信息”。

ExampleMode这个常量设置为false

在正式项目开发时,该常量需要修改成 false,就是关闭示例工程,关闭之后,就可以把根目录下的“Examples”删除。

执行完毕 AB 打包命令后,在 StreamingAssets 文件夹下,会出现 3个后缀为“.assetbundle”的 AB 包,这三个包就是 Examples 示例工程需要使用到的 AB 包。

0%