刚开始总是对这几个名词弄混,正好整理一下
完整框架基本是这样的:
http://doc.ulua.org/article/ngui/simpleframework_base1.html
https://blog.csdn.net/Momo_Da/article/details/52857219
一、什么是LuaFramework?答:基于SimpleFramework + tolua # 基础上,重新构造的新框架。框架内自带了LuaBundle模式(将Lua文件打包进Assetbundle) + 重构的资源管理器。
两大版本:
LuaFramework_NGUI:GitHub下载地址
LuaFramework_UGUI:GitHub下载地址
注:受限制于Unity在不断的版本更新中,Assetbundle的内部变更与机制更新,Github上作者LuaFramework也需要跟随版本进行填充内容,优化源码等,但更新已经跟不上Unity更新速度。使用中需要选择对应Unity版本的LuaFramework。解决的方法是,开发者自主基于现有框架添加新的机制和功能。或自主开发Lua框架以应对Unity各版本。
二、目的
理解LuaFramework原理。能够轻松自主开发框架或基于现有框架更新。
三、查看Lua项目
从Github上下载的LuaFramework,是一个完整的项目包。里面关于Lua的内容使用的均为绝对路径。在尚未清楚Lua的原理前,拖进至其他项目之中,会出现无法使用等报错原因。故Unity新建添加该项目。
其他:
Opening Project in Non-Matching Editor Installasion - 选择 “Continue”
API Update Required - 选择 “I Made a Backup. Go Ahead!”
一些问题: 2020版本无法打开。经检查目前LuaFramework仅提供2017/2018/2019的版本支持。在转2019版本时,出现反复加载某一段资源,长时间无法结束加载的情况。
3.1 操作流程(简)
打开Project窗口下 Framework->Scenes->mian场景:Hierarchy窗口下的GameManager对象上挂载有Main.cs。
第一次运行:[报错]没有找到框架所需要的资源,单击Game菜单下Build XXX Resources生成!
查看菜单栏:菜单栏上有 “LuaFramework” 和 "Lua"两新增菜单
打开Menu栏下 LuaFramework->Build Windows Resource:点击后,会在Project窗口新生成一个StreamingAssets目录。(注意:不同平台的Resource不一,根据需求平台进行选择。)
第二次运行:Game窗口出现由Lua实现的UI。
查看Console:梳理过程
3.2 流程梳理
前提操作:清理无用的DeBug
消息 描述 自上而下
Init lua state 初始化 LuaState
Register lua type cost time: XXX 注册 lua type 所耗费的时长
Initialize OK! 初始化完成
LuaState start 启用LuaState
[tolua.lua:11]:version20100 jit: XXX XXX 及时编译器版本信息
[tolua.lua:12]:os: Windows, arch: x64 Windows x64
[Main.lua:3]:logic start
3.3 MVC框架
参照LuaFramework->Scripts->Framework
M:Manager.cs
V:View.cs
C:Controller.cs
3.4 实现
参照LuaFramework->Scripts
3.4.1 关于Manager
GameManager:实现热更新的流程(关于实现的机制)
ResourceManager:从Assetsbundler中获取指定的Assets
LuaManager:初始化Lua语句来执行与Lua相关的内容
3.4.2 关于View
AppView(未被使用)
3.4.3 关于Controller
StartUpCommand:初始化管理器
3.5 打包
重新LuaFramework ->Build Window Resource
3.6 调试
变更AppConst.cs:2中的LuaBundleMode为Fasle
3.7 准备服务器
在服务器本地目录下新建命名文件夹,这里取名Lua_Test。
在新建目录Lua_Test下新建两个文件夹,分别取名为Release和Web。
Web:放置更新资源
Release:放置需要热更新的程序
将生成的StreamingAsset目录放置入Web目录中(也可是目录中整个文件)
使用Microsoft Edge或其他浏览器访问服务器
访问本地IP:http://local
访问局域网IP:http://192.168.0.1
访问远程服务器IP:http://IP
访问目录文件files.txt
IP地址:http://远程服务器IP/StreamingAssets/files.txt
搭建完成
四、热更新原理
Unity的热更新需要涉及到3个目录:
流程:
操作①仅第一次操作出现,是将游戏包资源文件拷贝至数据目录(后续将不再执行)
操作②请求网络资源,检查是否更新资源
操作③启动游戏程序
4.1 游戏资源目录:
包含Unity工程中StreamingAssets文件夹下的文件。安装游戏之后,这些文件将被复制到目标机器上特定的文件夹内。
注意:不同平台下的目录路径不一。
平台 路径
Mac OS或Windows Application.dataPath + "/StreamingAssets"
IOS Application.dataPath + "/Raw"
Android "jar:file://" + Application.dataPath + "!/assets/"
4.2 数据目录
“游戏资源目录”在Andriod、IOS上只读,无法将下载更新的资源放置其中。需建立一个“数据目录”,该目录可读写。
在第一次启动游戏后,程序会将“游戏资源目录”的内容复制到“数据目录中”。操作①
游戏过程中的资源加载,都将从“数据目录”中获取、解包。操作③
注意:不同平台下的目录路径不一。
平台 路径
Mac OS或Windows C:/LuaFramework/"
Android或IOS Application.persistendDataPath + "/LuaFramework""
调试模式下 Application.dataPath + “/StreamingAssets/”
4.3 网络资源地址
存放游戏资源的网址,游戏开始后,程序会从网络资源地址下载一些更新的文件到数据目录。
此目录下包含不同版本的资源文件,以及用于版本控制的files.txt。程序会优先下载此文件,然后与“数据目录”中文件的MD5码作比较,更新有变化的文件。操作②
LuaFramework的热更新代码定义在Assets\LuaFramework\Scripts\Manager\GameManager.cs【根据实际情况配置路径】
释放资源
//释放资源
void CheckExtractResource()
{
bool isExists = Dictionary.Exists(Util.DataPath)
&&Dictionary.Exists(Util.DataPath + "lua/")
&&Dictionary.Exists(Util.DataPath + "lua/");
if (isExists || AppConst.DebugMode)
{
StartCoroutine(OnUpdateResource())
return
}
StartCoroutine(OnExtractResource()) //启用释放协议
}
IEnumerator OnExtractResource()
{
string dataPath = Util.DataPath//数据目录
string resPath = Util.AppContentPath()//游戏包资源目录
if(Directory.Exists(dataPath) &&Directory.Delet(dataPath, true))
{
Directory.CreateDirectory(dataPath)
}
}
登录后复制
启用更新资源
IEnumerator OnUpdateMode()
{
if(!AppConst.UpdateMode)
{
OnResourceInited()
yield break
}
string dataPath = Util.DataPath //数据目录
string url = AppConst.WebUrl
string message = string.Empty
string random = DateTime.Now.ToString("yyyymmddhhmmss")
string listUrl = url + "files.txt?v=" + random
Debug.LogWarning("LoadUpdate ——>" + listUrl)
WWW www = new WWW(listUrl)
yield return www
if(www.error != null)
{
OnUpdateFaild(string.Empty)
yield break
}
}
登录后复制
五、代码热更新
5.1 修改配置
LuaFramework框架默认配置是从本地加载文件。需要打开AppConst.cs文件,
将UpdateMode设置为true,启用更新模式
将LuaBundleMode设置为true,启用热更新模式
修改WebUrl下的路径为对应服务器地址
5.2 配置"网络资源"
打开服务器,将工程项目中StreamingAssets里的所有内容复制到服务器上(必要时配置权限,让所有文件可下载)
5.3 测试热更新
修改Lua脚本(如将HelloLua改为LuaLuaLua)
点击Build Windows Resource
将"工程目录/StreamingAseets"里面的所有文件复制到服务器上。
再修改Lua脚本内容,覆盖本地资源。运行游戏,程序中出现"LuaLuaLua From Server"即证明网上拉去文件成功。
5.4 打包代码资源
File ->Build Setting ->PlayerSetting 更改相关描述
Build并上传至 服务器的Release目录下
5.5 上传代码资源
LuaFramework ->Build Windows Resource 更新Lua
将资源中新生成的StreamingAssets上传至 服务器Web目录下
5.6 其他Lua操作
Main.Lua
--主入口函数。 从此处开始Lua逻辑
local GameObject = UnityEngine.GameObject
function Main()
print("Logic Start")
local go = GameObject("test") --创建对象
go.transfrom.position = Vector3.one --设置坐标为(1,1,1)
end
登录后复制
Lua中使用.是极消耗性能,不提倡。如local go = UnityEngine.GameObject("Test"),应选择提前声明准备,如local GameObject = UnityEngine.GameObject,后续调用如local go = GameObject("Test")来降低性能消耗。
六、资源热更新
6.1 准备框架
参数设置:
设置AppConst.cs中ExampleMode为false(案例Lua,对正式打包无用)
设置AppConst.cs中LuaBundleMode为true(解决资源管理器中出现Lua文件,将其打包成Unity3D文件)
流程:
创建GameObject对象命名为"GameManager"(命名有严格要求,若更改须变更代码内容)
在GameManager游戏对象上添加(挂载)Main.cs脚本
在GameManager游戏对象上添加(挂载)Console.cs脚本(非LuaFramework内脚本,可忽略)
运行-检查有无报错
6.2 添加模型资源
向场景中添加若干模型资源。对必要操作模型创建Prefab预制体,放置对应资源文件夹内。
在LuaFramework框架下,Packager.cs内第77行添加如下代码:
//添加自定义资源
//AddBuildMap为脚本内提供方法 参数分别为 生成的Assetbundle文件名称 、 打包文件类型 、 文件目录
AddBuildMap("Tank" + AppConst.ExtName, "*.prefab", "Assets/Tanks/Prefabs")
登录后复制
6.3 打包模型资源
File ->Build Setting ->PlayerSetting 更改相关描述
Build并上传至 服务器的Release目录下
6.4 检查(可忽略)
--主入口函数。 从此处开始Lua逻辑
local GameObject = UnityEngine.GameObject
function Main()
print("Logic Start")
local luaHelper = LuaFramework.LuaHelper
local resMgr = luaHelper.GetResManager()
--参数 Assetbundle名字 资源名字 加载方法
resMger:LoadPrefab("Tank", {"TankPrefab"},OnLoaded) --LoadPrefab是实例方法,故使用 :
end
function OnLoaded(objs)
print("OnLoaded " .. type(objs))
end
6.5 上传模型资源
LuaFramework ->Build Windows Resource 更新Lua
将资源中新生成的StreamingAssets上传至 服务器Web目录下
首先需要确定开发语言,比如c,c++,java,python,php,.net等,当开发语言确定后就可以根据语法规则通过代码编辑器开始编写代码了。
软件开发学习是一个非常不错的选择,就目前软件开发而言java专业仍是比较吃香的一个专业,就业也是很不错的。
这专业会学习以下语言:C,JAVA,PHP,PYTHON,MYSQL,JAVASCRIPT另外就是各个语言的框架,提高开发速度的。下面是跟数据相关的知识。
1.如果没有语法错误, 则以函数形式返回编译好的代码块; 否则,返回 nil 加上错误消息。
如果结果函数有上值, env 被设为第一个上值。 若不提供此参数,将全局环境替代它。 所有其它上值初始化为 nil。 (当你加载主代码块时候,结果函数一定有且仅有一个上值 _ENV ))。 然而,如果你加载一个用函数(参见 string.dump, 结果函数可以有任意数量的上值) 创建出来的二进制代码块时,所有的上值都是新创建出来的。 也就是说它们不会和别的任何函数共享。
2.接下来就是根据以上信息进行下面的操作,chunkname 在错误消息和调试消息中,用于代码块的名字。 如果不提供此参数,它默认为字符串chunk 。 chunk 不是字符串时,则为 "=(load)" 。
字符串 mode 用于控制代码块是文本还是二进制(即预编译代码块)。 它可以是字符串 "b" (只能是二进制代码块), "t" (只能是文本代码块), 或 "bt" (可以是二进制也可以是文本)。 默认值为 "bt"。
3.Lua 不会对二进制代码块做健壮性检查。 恶意构造一个二进制块有可能把解释器弄崩溃。
运行程序来遍历表中的所有域。 第一个参数是要遍历的表,第二个参数是表中的某个键。 next 返回该键的下一个键及其关联的值。 如果用 nil 作为第二个参数调用 next 将返回初始键及其关联值。 当以最后一个键去调用,或是以 nil 调用一张空表时, next 返回 nil。 如果不提供第二个参数,将认为它就是 nil。 特别指出,你可以用 next(t) 来判断一张表是否是空的。
索引在遍历过程中的次序无定义, 即使是数字索引也是这样。 (如果想按数字次序遍历表,可以使用数字形式的 for 。)
4.当在遍历过程中你给表中并不存在的域赋值, next 的行为是未定义的。 然而你可以去修改那些已存在的域。 特别指出,你可以清除一些已存在的域。
如果 t 有元方法 __pairs, 以 t 为参数调用它,并返回其返回的前三个值。
否则,返回三个值:next 函数, 表 t,以及 nil。
5.传入参数,以 保护模式 调用函数 f 。 这意味着 f 中的任何错误不会抛出; 取而代之的是,pcall 会将错误捕获到,并返回一个状态码。 第一个返回值是状态码(一个布尔量), 当没有错误时,其为真。 此时,pcall 同样会在状态码后返回所有调用的结果。 在有错误时,pcall 返回 false 加错误消息。
希望能帮到你,谢谢!
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)