unity3d 单机游戏有必要用i7吗做热更新吗

扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
_____________________________________________________________________________________________________________
问答求助版块规则:
  1、问题尽量描述清楚
& && &2、代码要放在代码块里
& && &3、附件最好放到云盘,然后把链接放到TXT文档里,上传TXT文档。【最好没有附件,你懂得】
& && &4、本版块回复不得无意义,如:顶、呵呵、不错......以及擦边!【真的会扣分的哦】严重者,封IP!
& && &5、问题得到解决,请选择最佳答案。
& && &6、若问题是你自己解决了,可以联系管理员,返还蛮牛币,写下你的答案,另有蛮牛币奖赏。
_____________________________________________________________________________________________________________
查看: 446|回复: 6
求助热更新问题,比较小白
2125/150排名<font color="#FF昨日变化10主题帖子积分
初来乍到, 积分 125, 距离下一级还需 25 积分
初来乍到, 积分 125, 距离下一级还需 25 积分
在线时间59 小时
在网上看到好多的热更新方案,感觉都没看明白,有的是c#写的更新lua有的是lua写的,不太明白 , 所需要更新的工程必须是lua编写的么?
每日推荐:
73034/5000排名<font color="#FF昨日变化16主题帖子积分
日久生情, 积分 3034, 距离下一级还需 1966 积分
日久生情, 积分 3034, 距离下一级还需 1966 积分
蛮牛币8310
在线时间400 小时
来自Mobile---
用Lua是很不错,不过c#也可以啊,WWW更新资源
每日推荐:
5647/1000排名<font color="#FF昨日变化1主题帖子积分
熟悉之中, 积分 647, 距离下一级还需 353 积分
熟悉之中, 积分 647, 距离下一级还需 353 积分
蛮牛币3171
在线时间166 小时
这个看你是什么工程了,,,PC 工程,WWW 资源更新机制就可以满足更新需求, 手机工程,由于 文件夹的读写限制,以及 IOS的限制,才使用lua&&进行代码方面更新的~
每日推荐:
3286/300排名<font color="#FF昨日变化3主题帖子积分
偶尔光临, 积分 286, 距离下一级还需 14 积分
偶尔光临, 积分 286, 距离下一级还需 14 积分
在线时间69 小时
tolua的luaFramework框架可以用
每日推荐:
2125/150排名<font color="#FF昨日变化10主题帖子积分
初来乍到, 积分 125, 距离下一级还需 25 积分
初来乍到, 积分 125, 距离下一级还需 25 积分
在线时间59 小时
这个看你是什么工程了,,,PC 工程,WWW 资源更新机制就可以满足更新需求, 手机工程,由于 文件夹的读写 ...
看了tolua ,貌似它是c#代码更新的lua文件代码,所以必须用lua写需要更新的部分,
每日推荐:
5647/1000排名<font color="#FF昨日变化1主题帖子积分
熟悉之中, 积分 647, 距离下一级还需 353 积分
熟悉之中, 积分 647, 距离下一级还需 353 积分
蛮牛币3171
在线时间166 小时
看了tolua ,貌似它是c#代码更新的lua文件代码,所以必须用lua写需要更新的部分, ...
我也刚刚研究代码更新~~有点蛋疼~
[]: 绝世love情缘 乐于助人,奖励 1
每日推荐:
2125/150排名<font color="#FF昨日变化10主题帖子积分
初来乍到, 积分 125, 距离下一级还需 25 积分
初来乍到, 积分 125, 距离下一级还需 25 积分
在线时间59 小时
我也刚刚研究代码更新~~有点蛋疼~
好吧, 坐等大腿。
每日推荐:【Unity3D】让你的游戏支持热更新
【Unity3D】让你的游戏支持热更新
&作者:蝎子马戏团& &来源:
1、在Unity中引入lua的主要原因:& &&&1.1,Unity不支持代码热更新& &&&C#在ios平台不支持热更新,在Android平台热更新也比较麻烦,而lua支持热更新。& & 1.2,为了能够前后台复用关键逻辑代码& &&&Unity前台使用C#,后台使用C或C++,属性计算和战斗系统代码无法复用,通过lua可以方便实现前后台关键逻辑代码共用。 2、lua插件的选择:& & 2.1 UniLua& & 云风团队的作品,纯C#实现,但使用起来很麻烦,比较鸡肋。& &&&2.2 uLua& & & &&&uLua是 Lua 、LuaJIT 、LuaInterface的集合,Unity主流的lua插件, AssertStore上售价40美刀。& & C#调用lua脚本和从lua脚本中访问C#对象都方便,接下来我们简单了解一下uLua,然后通过一个简单的Demo来深入了解uLua的使用。 3、C#调用lua脚本& && && &基本保持了和C++相同的调用方式,对于用过tolua++的同学非常亲切& && & // 初始化lua脚本 //FLuaMgr.Instance.Init();
// 调用Test.lua中的 lua脚本函数//FLuaMgr.Instance.PCall("Test.ChangeMyClassProperty");
4、lua访问C#对象属性及函数& && && &uLua利用.Net的反射机制,直接从dll中导出C#类定义。& && && &这一块功能是通过Lua.cs实现的,具体实现机制比较复杂,我们看一个简答的例子:& && && &4.1 导入C#类UnityEngine& &&&= luanet.UnityEngineSystem& && && & = luanet.System
--- UnityEngine Classes---Debug& && && &&&= UnityEngine.DebugGameObject& && &= UnityEngine.GameObjectCamera& && && & = UnityEngine.CameraTransform& && & = UnityEngine.Transform
--- Our Classes ---luanet.load_assembly('Assembly-CSharp')MyClass = luanet.import_type('MyClass') & && & 通过这几句代码,我们就将UnityEngine的Debug、GameObject、Camera、Transform类导入进来了,此外将我们自定义的C#类MyClass也导入进了lua。这比用tolua++导出C++对象简单多了。& && &&&4.2 在lua使用使用C#导入类local myClass = GameObject.Find("MyClass"):GetComponent("MyClass");
myClass.DisplayName = "ChangedName From Lua";local box1 = myClassrawBox(1); & && && &GameObject .Find和GetComponent是Unity常用函数,通过uLua可以在lua中直接访问,这是uLua的重要优势。& && && &此外我们定义类MyClass的属性和函数也可以同样方便的调用,这样扩展起来非常方便。
5、加载lua脚本的优化& && && &创建一个LuaState, 然后使用LuaState的DoString就可以加载lua脚本;LuaState luaState = new LuaState();luaState.DoString("print('hello world')"); & && && &这样虽然可以加载lua,但是这并不能满项目需求,笔者封装了一个FLuaMgr& && &&&在FLuaMgr的Init函数中加载lua文件下的所有lua文件: // 直接读取TextAsset//private bool DoDirFilesByTextAsset(string path){& & TextAsset[] luaCodes = Resources.LoadAll(path);& & for (int i = 0; i & luaCodes.L i++)& & {& && &&&string fileName = luaCodes.& && &&&//Debug.Log("FileName=" + fileName);& && &&&int prefabEnd = fileName.LastIndexOf(GenLuaFileEnding); // 判断是否是lua文件 //& && &&&if (prefabEnd &= 0)& && &&&{& && && && &FDebug.LogWarning("FileName=" + fileName + " is not a lua file!");& && && && && && &&&}
& && &&&DoString(luaCodes.text, fileName);& & }& & // 卸载lua脚本文件 //& & Resources.UnloadUnusedAssets();& &} & && &5.1 Unity 只能识别.txt文件文件的解决办法& && & 在Assets/Lua 文件夹编辑lua脚本,然后通过ConvertToLuaTxt 转化到Assets/LuaGen文件夹下。具体内容参考Demo中的ConvertToLuaTxt.cs 6、Unity中嵌入lua的Demo介绍& && && &将附件中的uLuaExample.unitypackage 导入到一个空的Unity项目,然后打开LuaTest.unity,直接运行,lua脚本调用MyClass的函数绘制若干个矩形、球和圆柱体。-- 调用C#对象的函数function DrawSomeBoxes()& && && && &&&-- 直接调用GameObject的导出函数Find,类导出查看ImportClass.lua& && && && &&&local myClass = GameObject.Find("MyClass"):GetComponent("MyClass");
& && && && &&&-- 调用我们的C#类MyClass.DrawBox(float size)& && && && &&&local box1 = myClassrawBox(1);& && && && &&&box1.transform.position = Vector3(-5,-2.5,0);
& && && && &&&local box2 = myClassrawBox(1.25);& && && && &&&box2.transform.position = Vector3(-5,-1.0,0);
& && && && &&&local box3 = myClassrawBox(1.5);& && && && &&&box3.transform.position = Vector3(-5,1.5,0);end & && &&&执行效果图:& && && &
& & & & & & & & & & & & & & & & & && && &创建对象和位置排列逻辑由Test.lua实现。7、lua执行效率& && && &7.1 加载所有lua脚本的消耗& && && && && && & 笔者所在的项目有13个lua文件,lua脚本总行数1127行。& && && && && && &
& & & & & & & & & & & & & & & & & && && && && && & 在华为荣耀3手机上初始化lua平均耗时270ms。& && && &7.2 执行简单的lua函数的效率:function SimpleLuaFunc()& && && && &&&local id = 1;& && && && &&&if (id & 1)& && && && &&&then& && && && && && && && && & print("id & 1");& && && && &&&endend & && && &
& & & & & & & & & & & & & & & &
一次简单的lua调用平均耗时9微秒,性能在可接受的范围内。范围内。
发表评论:
馆藏&20646
TA的推荐TA的最新馆藏[转]&[转]&[转]&[转]&[转]&[转]&之前写了Unity3D热更新全书系列Blog
提出了下载、加载、脚本三个方面的开源类库
下载方面有EasyDown加载方面有GameObjParser脚本方面有C#Light另外有一个没有独立成库,但是到处都用的Myjson。
2015,重头思考这些事情,有了不一样的感悟,于是也有了新的规划
1.首先了C#Light的语法解释问题变得臃肿低效,重头开始了L#项目。目前L#项目已经进入Beta阶段,完全可以全面替换C#Light。MyJson也独立成库2.下载方面,Easydown是基于经典的文件名索引,版本库核对的模式,继续用没什么问题但不符合我对资源库的预期于是有了一个替代项目CloudSand,云沙,云沙的目标是打破发布者和下载者的界限,随时发布,随时更新。不再使用 准备原始资源-》打包制作版本库-》上传http服务器-&客户端下载 的流程而变成 随时上传-&发布-&其他人更新 的流程3.加载方面,原来的GameObjParser是适配EasyDown的,而且功能也浅尝辄止,只能用来对部分预设进行存取。比如NGUI。规划了一个CleanData用来替代GameObjParser,适配CloudSand
热更新这件事,意义是非常的重大的,我一直执着于热更新,并非是处于纯粹的技术追求天下武功,无坚不破,唯快不破。我要做产品,开发到用户的速度,将是非常重要的一点。甚至打破开发和用户的界限,这也是我想要产品体现出来的特点,而且拥有重大的意义在积累了足够的经验之后,我可以把这些东西整合到一起来了。
于是2015,将原先分散的开源类库,重整为FB引擎系列。
设置了统一的主页
新的FB引擎系列(热更新相关):1.L#
dotnet通用, 全平台可用脚本引擎,直接执行dotnet DLL,类似反射用法,但不受AOT制约
已Beta,可用,IOS WP8 均测过2.MyJson
dotnet 通用,快速简洁的json处理类库,可用于u3d,大量项目中使用过,比较稳定3.CloudSand
U3D专用,资源上传下载一揽子方案,内部开发状态4.CleanData
U3D专用,预设不打AssetBundle,通过自定义格式全平台通用的加载存储方案,内部开发状态5.CleanAni
U3D专用,骨骼动画不打AssetBundle,通过自定义格式全平台通用的存储,回放,编辑方案,内部开发状态以下仅在规划中6.CleanEffect
U3D专用,新的特效系统,通过自定义格式全平台通用,并优化。7.CleanSound
U3D专用,新的音效系统,通过Ogg格式,实现全平台加载并解码播放Ogg其他:FB引擎是一个动作游戏引擎其他相关还有很多工作,暂不公布
阅读(...) 评论()声明:本文介绍的热更新方案是我在网上搜索到的,然后自己修改了一下,相当于是借鉴了别人的思路,加工成了自己的,在此感谢无私分享经验的们。想要使用热更新,需要规划设计好资源比较策略,资源版本,确保增加新资源后可以下载到本地,有资源更新的时候可以替换掉本地旧资源。我在前面写了一篇“unity 打包AssetBundle”的,里面生成了一个资源版本文件,不多解释了,上图。至于怎么生成这个文件的,可以看一下我前面写的文章。废话不多说。650) this.width=650;" src="/upload/images//311.png" title="QQ图片32.png" alt="wKioL1er5uqQ3DVFAAI62J8DbGQ610.png-wh_50" />先介绍热更新步骤,后上代码步骤一、在Resources目录下新建一个文本,名称是bundle_list(后缀是.txt),内容如下:&&&&{"id":0,"":"1.0","manifest":"","resource":{}},当然您可以根据自己&&&&实际情况来设计json格式。资源上也会有一份格式相同的bundle_list步骤二、如果是第一次进入,Application.persistentDataPath目录下还没有bundle_list文件,这&&&&&&&&&&&&时候就需要用Resources.Load方法从Resources目录中加载出来。否则&&&&&&&&&&&&加载Application.persistentDataPath目录下的bundle_list步骤三、从资源服务器下载bundle_list文件步骤四、获取本地bundle_list的id和资源服务器下载的bundle_list中的id,做对比,如果前者等于后者,&&&&&&&&&&&&则不需要更新,如果前者小于后者,则需要更新。步骤五、分别解析出本地和资源服务器bundle_list中的资源路径名称,名称相同的,对比hash值,相同&&&&则不需要更新,反之,更新。如果资源服务器有的名称本地没有,则表示是新增资源,需要&&&&下载到本地。步骤六、把资源服务器的bundle_list覆盖本地bundle_list。热更新完成。代码:using UnityEusing .Cusing System.Collections.Gusing System.Tusing System.IO;using LitJ/**&* 资源增量更新&* 1.检查本地Application.persistentDataPath目录中是否有bundle_list文件&* 2.如果没有,则从Resources目录中读取bundle_list文件&* 3.从服务器上下载bundle_list文件,判断版本是否一致,如果一致就不用更新&* 4.版本不一致,需要更新,更新&* 5.将最新的bundle_list存入Application.persistentDataPath目录中&**/public class Bundle : MonoBehaviour{& & private static readonly string VERSION_FILE = "bundle_list";& & private string SERVER_RES_URL = "";& & private string LOCAL_RES_URL = "";& & private string LOCAL_RES_PATH = "";& & /// &summary&& & /// 本地版本json对象& & /// &/summary&& & private JsonData jdLocalF& & /// &summary&& & /// 版本json对象& & /// &/summary&& & private JsonData jdServerF& & /// &summary&& & /// 本地资源名和路径字典& & /// &/summary&& & private Dictionary&string, string& LocalBundleV& & /// &summary&& & /// 服务器资源名和路径字典& & /// &/summary&& & private Dictionary&string, string& ServerBundleV& & /// &summary&& & /// 需要下载的文件List& & /// &/summary&& & private List&string& NeedDownF& & /// &summary&& & /// 是否需要更新本地版本文件& & /// &/summary&& & private bool NeedUpdateLocalVersionFile =& & /// &summary&& & /// 下载完成委托& & /// &/summary&& & /// &param name="www"&&/param&& & public delegate void HandleFinishDownload(WWW www);& & /// &summary&& & /// 本次一共需要更新的资源数& & /// &/summary&& & int totalUpdateFileCount = 0;& & void Start()& & {#if UNITY_EDITOR && UNITY_ANDROID & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & & &&& & & & SERVER_RES_URL = "file:///" + Application.streamingAssetsPath + "/android/";& & & & LOCAL_RES_URL = "file:///" + Application.persistentDataPath + "/res/";& & & & LOCAL_RES_PATH = Application.persistentDataPath + "/res/";#elif UNITY_EDITOR && UNITY_IOS& & & & SERVER_RES_URL = "file://" + Application.streamingAssetsPath + "/ios/";& & & & LOCAL_RES_URL = &"file:///" + Application.persistentDataPath + "/res/";& & & & LOCAL_RES_PATH = &Application.persistentDataPath + "/res/";#elif UNITY_ANDROID& & & & //安卓下需要使用www加载StreamingAssets里的文件,Streaming Assets目录在安卓下的路径为 "jar:file://" + Application.dataPath + "!/assets/"& & & & SERVER_RES_URL = &"jar:file://" + Application.dataPath + "!/assets/" + "android/";& & & & LOCAL_RES_URL = &"jar:file://" + Application.persistentDataPath + "!/assets/" + "/res/";& & & & //LOCAL_RES_URL = &"file://" + Application.persistentDataPath + "/res/";& & & & LOCAL_RES_PATH = &Application.persistentDataPath + "/res/";#elif UNITY_IOS& & & & SERVER_RES_URL = "http://127.0.0.1/resource/ios/"& & & & LOCAL_RES_URL = &"file:///" + Application.persistentDataPath + "/res/";& & & & LOCAL_RES_PATH = &Application.persistentDataPath + "/res/";#endif& & & & //初始化 & && & & & LocalBundleVersion = new Dictionary&string, string&();& & & & ServerBundleVersion = new Dictionary&string, string&();& & & & NeedDownFiles = new List&string&();& & & & //加载本地version配置 & && & & & string tmpLocalVersion = "";& & & & if (!File.Exists(LOCAL_RES_PATH + VERSION_FILE))& & & & {& & & & & & TextAsset text = Resources.Load(VERSION_FILE) as TextA& & & & & & tmpLocalVersion = text.& & & & }& & & & else& & & & {& & & & & & tmpLocalVersion = File.ReadAllText(LOCAL_RES_PATH + VERSION_FILE);& & & & }& & & & //保存本地的version & && & & & ParseVersionFile(tmpLocalVersion, LocalBundleVersion, 0);& & & & //加载服务端version配置 & && & & & StartCoroutine(this.DownLoad(SERVER_RES_URL + VERSION_FILE, delegate (WWW serverVersion)& & & & {& & & & & & //保存服务端version & && & & & & & ParseVersionFile(serverVersion.text, ServerBundleVersion, 1);& & & & & & //计算出需要重新加载的资源 & && & & & & & CompareVersion();& & & & & & //加载需要更新的资源 & && & & & & & DownLoadRes();& & & & }));& & }& & //依次加载需要更新的资源 & && & private void DownLoadRes()& & {& & & & if (NeedDownFiles.Count == 0)& & & & {& & & & & & UpdateLocalVersionFile();& & & & & && & & & }& & & & string file = NeedDownFiles[0];& & & & NeedDownFiles.RemoveAt(0);& & & & StartCoroutine(this.DownLoad(SERVER_RES_URL + file, delegate (WWW w)& & & & {& & & & & & //将下载的资源替换本地就的资源 & && & & & & & ReplaceLocalRes(file, w.bytes);& & & & & & DownLoadRes();& & & & }));& & }& & private void ReplaceLocalRes(string fileName, byte[] data)& & {& & & & try& & & & {& & & & & & string filePath = LOCAL_RES_PATH + fileN& & & & & & if (!File.Exists(filePath))& & & & & & {& & & & & & & & string p = Path.GetDirectoryName(filePath);& & & & & & & & if (!Directory.Exists(p))& & & & & & & & & & Directory.CreateDirectory(p);& & & & & & }& & & & & & File.WriteAllBytes(filePath, data);& & & & }& & & & catch (System.Exception e)& & & & {& & & & & & Debug.Log("e is " + e.);& & & & }& & }& & //更新本地的version配置 & && & private void UpdateLocalVersionFile()& & {& & & & if (NeedUpdateLocalVersionFile)& & & & {& & & & & & if (!Directory.Exists(LOCAL_RES_PATH))& & & & & & & & Directory.CreateDirectory(LOCAL_RES_PATH);& & & & & & StringBuilder versions = new StringBuilder(jdServerFile.ToJson());& & & & & & FileStream stream = new FileStream(LOCAL_RES_PATH + VERSION_FILE, FileMode.Create);& & & & & & byte[] data = http://chenshuhb./6087203/Encoding.UTF8.GetBytes(versions.ToString());& & & & & & stream.Write(data, 0, data.Length);& & & & & & stream.Flush();& & & & & & stream.Close();& & & & }& & }& & private void CompareVersion()& & {& & & & int localVersionId;& & & & int serverVersionId;& & & & if (jdLocalFile != null && jdLocalFile.Keys.Contains("id"))& & & & & & localVersionId = (int)jdLocalFile["id"];& & & & if (jdServerFile != null && jdServerFile.Keys.Contains("id"))& & & & & & serverVersionId = (int)jdServerFile["id"];#if UNITY_ANDROID || UNITY_EDITOR& & & & NeedDownFiles.Add("android");#endif#if UNITY_IOS#endif& & & & foreach (var version in ServerBundleVersion)& & & & {& & & & & & string fileName = version.K& & & & & & string serverHash = version.V& & & & & & //新增的资源 & && & & & & & if (!LocalBundleVersion.ContainsKey(fileName))& & & & & & {& & & & & & & & NeedDownFiles.Add(fileName);& & & & & & }& & & & & & else& & & & & & {& & & & & & & & //需要替换的资源 & && & & & & & & & string localH& & & & & & & & LocalBundleVersion.TryGetValue(fileName, out localHash);& & & & & & & & if (!serverHash.Equals(localHash))& & & & & & & & {& & & & & & & & & & NeedDownFiles.Add(fileName);& & & & & & & & }& & & & & & }& & & & }& & & & totalUpdateFileCount = NeedDownFiles.C& & & & //本次有更新,同时更新本地的version.txt & && & & & NeedUpdateLocalVersionFile = NeedDownFiles.Count & 0;& & }& & /// &summary&& & ///&& & /// &/summary&& & /// &param name="content"&&/param&& & /// &param name="dict"&&/param&& & /// &param name="flag"&0表示本地版本文件,1表示服务器版本文件&/param&& & private void ParseVersionFile(string content, Dictionary&string, string& dict, int flag)& & {& & & & if (content == null || content.Length == 0)& & & & {& & & & & && & & & }& & & & JsonData jd =& & & & try& & & & {& & & & & & jd = JsonMapper.ToObject(content);& & & & }& & & & catch (System.Exception e)& & & & {& & & & & & Debug.LogError(e.Message);& & & & & && & & & }& & & & if (flag == 0)//本地& & & & {& & & & & & jdLocalFile =& & & & }& & & & else if (flag == 1)//服务器& & & & {& & & & & & jdServerFile =& & & & }& & & & else& & & & & && & & & //获取资源对象& & & & JsonData resObjs =& & & & if (jd.Keys.Contains("resource"))& & & & & & resObjs = jd["resource"];& & & & if (resObjs != null && resObjs.IsObject && resObjs.Count & 0)& & & & {& & & & & & string[] resNames = new string[resObjs.Count];& & & & & & resObjs.Keys.CopyTo(resNames, 0);& & & & & & for (int i = 0; i & resNames.L i++)& & & & & & {& & & & & & & & if (resObjs.Keys.Contains(resNames[i]))& & & & & & & & & & dict.Add(resNames[i], resObjs[resNames[i]].ToString());& & & & & & }& & & & }& & }& & private IEnumerator DownLoad(string url, HandleFinishDownload finishFun)& & {& & & & WWW www = new WWW(url);& & & && & & & if (!string.IsNullOrEmpty(www.error))& & & & {& & & & & & Debug.LogError("www.error is " + www.error);& & & & & && & & & }& & & & if (finishFun != null)& & & & {& & & & & & finishFun(www);& & & & }& & & & www.Dispose();& & }}以上是提供了一个热更新思路,水平有限,有写的不对和需要优化的地方,还请不吝赐教!}

我要回帖

更多关于 网卡驱动有必要更新吗 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信