unity3D加密
Posted mb630ec035bcfe8
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity3D加密相关的知识,希望对你有一定的参考价值。
打包资源,加载资源已经是ungity3d很常见的事了,其中为了自己的资源不被别人抄袭,经常会将已经打包好的“xx.unity3d”机密,一种是在外边加一次“保护膜”(比如建个文件夹,把文件夹加密,这种我没研究过),另一种就是把“.unity3d”包转换成“.byte”文件,把转换好的“.byte”文件用一定的规律乱掉(规律要记好,解密时还要用),然后再把“.byte”文件打包成“.unity3d”文件,这样打包完的“.unity3d”资源包必须经过两次加载和一次生成才能使用,第一次是加载成“.byte”文件,然后将“.byte”文件生成“.unity3d”虚拟资源包,最后再加载生成的虚拟资源包里的真实资源(中间需要解密)。
打包资源我就不谈论了,网上有具体的代码,今天主要说说解密时遇到的问题,把".byte"文件加载成“.unity3d”包需要用到AssetBundle.CreateFromMemory(byte[] bytes)方法,这是一个从内存字节生成资源包的方法,返回的是 AssetBundleCreateRequest类型,同是返回的有一个数据流,这就需要用到协同程序(主要是yield return AssetBundleCreateRequest),而第一次加载也需要用到协同程序,因此网上给了一种协同里面套协同的方法。我试着用了一下,发现这个加载脚本需要继承MonoBehaviour类,但是加载资源的脚本里面不需要用到Start()和Update()方法,只是写了一些公开的方法而已,因此不必继承 MonoBehaviour类,因此StartCoroutine方法就不能使用,所以网上给的协同里面套协同就不合适了,于是我就开始了苦逼的一天。
开始我想在第一次加载的方法(LoadAsset())里面另开个线程,通过线程调用第二次加载(LoadBundle())方法,但是系统报错,说IEnumerator调用必须在主线程中,我郁闷了,所以我就开始查关于AssetBundleCreateRequest的文档,并开始用普通方法调用:因为IEnumerator返回的肯定是IEnumerator类,所以我声明了一个IEnumerator类型的ie变量接受IEnumerator的返回值,然后调用IEnumerator.MoveNext()方法,这样就把AssetBundleCreateRequest类返回给我了,我开始很高兴,因为得到AssetBundleCreateRequest后就可以通过AssetBundleCreateRequest.progress和AssetBundleCreateRequest.isDown查看进度,等到AssetBundleCreateRequest.progress >=1就表明“.unity3d”包创建完成(这是虚拟包,可以直接加载),然后我就可以加载,最后实例化,这就完成了,但是事实没有我想的那么完美,出现了一个意想不到事情,AssetBundleCreateRequest.progress和AssetBundleCreateRequest.isDown竟然不同步,progress显示的是1,按说isDown应该是true,但事实却是false,这很让我费解,然后我就去查这两个到底代表了什么意思,最后发现progress确实是下载进度,但isDown确是是否完成操作,也就是AssetBundleCreateRequest这个异步操作是否完成,这就坑爹了,AssetBundleCreateRequest是继承了AsyncOperation 类,但是这是unity3d自己封装的,不是c#封装的,官网上也没明确给出AsyncOperation 异步操作的终止方法,等于说打了个死结了。就在我以为只能认命时(脚本继承MonoBehaviour)时,突然发现自己脑残了,你妹的别人博客上把二个协同写成一个套一个,我可以把两个协同写在一起啊,一个yield return WWW,一个yield return AssetBundleCreateRequest。完全可以解决不必继承MonoBehaviour的事情,至于为什么这么做,下次再说吧,下面我将代码传上。
1. public class ResourceManager
2.
3. bool isloadfromCache = true;//是否从缓存加载
4. private static ResourceManager resourceManager;
5. int m_CacheVersion = 5;//版本号
6.
7.
8. //实例化
9. public static ResourceManager getInstance()
10.
11. if(resourceManager == null)
12.
13. resourceManager = new ResourceManager();
14.
15. return resourceManager;
16.
17.
18. //构造方法
19. public ResourceManager()
20.
21. //我用的是本地加载,网络需要用“http://”
22. mResourcePath = "file://" + Application.dataPath;
23.
24.
25. //协同程序,需要用StartCoroutine()方法调用,可以外部调用
26. public IEnumerator LoadAsset(string fileName)
27.
28. string fullurl = mResourcePath + "/" + "Unity3d/"+fileName+".unity3d"; //加载路径
29. WWW m_Download;
30. if(isloadfromCache)
31. m_Download = WWW.LoadFromCacheOrDownload(fullurl,m_CacheVersion);
32. else
33. m_Download = new WWW(fullurl);
34.
35. //第一次协同
36. yield return m_Download;
37. if(m_Download.error != null)
38.
39. // Debug.LogError(m_Download.error);
40. Debug.Log("Warning errow"+fileName);
41. yield break;
42.
43. //第一次加载
44. TextAsset txt = m_Download.assetBundle.Load(fileName,typeof(TextAsset)) as TextAsset;
45. byte[] data = txt.bytes;
46. byte[] decryptedData = Decryption(data);
47. //打成虚拟包
48. AssetBundleCreateRequest acr = AssetBundle.CreateFromMemory(decryptedData);
49. //原本要第二次协同
50. yield return acr;
51. AssetBundle bundle = acr.assetBundle;
52. //第二次加载
53. bundle .LoadAll();
54. Instantiate(bundle.mainAsset);
55.
56. byte[] Decryption(byte[] data)
57. //解密算法,这个要自己写,你加密时是怎样,这里反过来
58.
59.
60.
以上是关于unity3D加密的主要内容,如果未能解决你的问题,请参考以下文章