感谢原文作者:知乎@罗培羽 (以下因为框架版本等原因对原作稍有改动)
热更新涉及资源热更新和代码热更新(其实lua代码也是资源),那接下来看看如何动态加载一个prefab。这一部分涉及资源打包、动态创建资源等内容。
可以参考这篇文章:
http://blog.csdn.net/husheng0/article/details/48577787
为了调试的方便,先将框架配置为本地模式,待测试热更新时再改成更新模式。
图:配置为本地模式
先测试个简单的创建物体,新建一个名为go的物体,然后设置它的坐标为(1,1,1)。这段代码虽然不涉及资源加载,但能展示“把物体添加到场景中”的过程。Main.lua的代码如下:
[C#]
1 2 3 |
function Main() local go = UnityEngine.GameObject ('go') go.transform.position = Vector3.one end |
图:动态创建一个名为go的空物体
要热更新资源,便需要制作资源。这里制作一个名为cubePrefab的立方体cube预设,贴上贴图,然后存到Assets/TestPack目录下。接下来对它做打包,然后动态加载。
LuaFramework在打包方面并没有做太多的工作,我们需要手动打包。打开Assets/LuaFramework/Editor/Packager.cs,按照示例的写法,加上下面这一行:将Assets/TestPack目录下的所有预设(.prefab)打包成名为TestPack的包。
进入 static void HandleExampleBundle(BuildTarget t)函数,添加:get)
代码:
assetfile = assetPath + "TestPack" + AppConst.ExtName;
mainAsset = LoadAsset("TestPack/Cube.prefab");
BuildPipeline.BuildAssetBundle(mainAsset, null, assetfile, options, target);
图:修改打包代码
点击“Build Windows Resource”,即可在StreamingAssets中看到打包好的文件。
图:cube资源的包文件
如下图所示,Unity3D资源包里面包含多个资源,就像一个压缩文件一样。在动态加载的时候,便需要有加载包文件、或取包中的资源两步操作(框架已经帮我们做好了这部分工作,直接调用API即可)。
图:Unity3D的资源包
2.3.1 在框架提供的资源管理器中添加函数
步骤1、打开ResourseManager.cs 添加LoadPrefab函数:
代码:
//新添加从bundle中 读取prefab的函数
public GameObject LoadPrefab(string bundleName, string prefabName, Action func)
{
GameObject newPrefab = null;
string uri = Util.DataPath + bundleName + AppConst.ExtName;
Debug.LogWarning("@LoadPrefab:LoadFile::>> " + uri);
AssetBundle ab = AssetBundle.LoadFromFile(uri);
#if UNITY_5
newPrefab = ab.LoadAsset(prefabName, typeof(GameObject)) as GameObject;
#else
newPrefab = ab.Load("prefabName", typeof(GameObject)) as GameObject;
#endif
if (func != null)
{
func(); //资源获取成功,回调func,执行后续操作
}
return newPrefab;
}
步骤2、在Unity编辑器中选择lua->Genarate All ,注册这个函数,方便lua中直接使用 ,否则会出现xx函数未定义的错误(重要)
2.3.2 在lua中通过资源管理器动态加载prefab,动态创建prefab
编写如下lua代码(main.lua),使用2.3.1我们在资源管理器(ResourseManager)中添加的函数加载testPack包的cube文件,加载完成后Instantiate实例化对象。
--主入口函数。从这里开始lua逻辑
代码:
--主入口函数。从这里开始lua逻辑
function Main()
LuaFramework.Util.Log("*******lua脚本新建一个Cube开始*******");
LuaHelper = LuaFramework.LuaHelper;
resMgr = LuaHelper.GetResManager();
local cube = resMgr:LoadPrefab('TestPack', 'Cube', OnLoadPrefabFinish);
local go = UnityEngine.GameObject.Instantiate(cube);
go.transform.position = Vector3(0,0,0);
LuaFramework.Util.Log("*******lua脚本新建一个Cube完成*******");
-- 由于例子camara的干扰,我们让主摄像机层级更高
UnityEngine.Camera.allCameras[0].depth = 1;
end
--场景切换通知
function OnLevelWasLoaded(level)
Time.timeSinceLevelLoad = 0
end
--加载完成后的回调--
function OnLoadPrefabFinish(objs)
LuaFramework.Util.Log("@main.lua: Finish load cube!");
end
完成后运行游戏,即可看到动态加载出来的模型。
图:动态加载出来的模型
“资源热更新”和使用指南第一章节的“代码热更新”完全相同,开启更新模式后,将新的资源文件复制到服务器上,框架即可自动下载更新的资源。这里不再复述。