zoukankan      html  css  js  c++  java
  • u3d外部资源加载加密

    原文地址:http://www.cnblogs.com/88999660/archive/2013/04/10/3011912.html

    首先要鄙视下unity3d的文档编写人员极度不负责任,到发帖为止依然没有更新正确的示例代码。

    // C# Example
        // Builds an asset bundle from the selected objects in the project view.
        // Once compiled go to "Menu" -> "Assets" and select one of the choices
        // to build the Asset Bundle
         
        using UnityEngine;
        using UnityEditor;
        using System.IO;
        public class ExportAssetBundles {
            [MenuItem("Assets/Build AssetBundle Binary file From Selection - Track dependencies ")]
            static void ExportResource () {
                // Bring up save panel
                string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d");
                if (path.Length != 0) {
                    // Build the resource file from the active selection.
                    Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
                    BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets);
                    Selection.objects = selection;
                 
             
                    FileStream fs = new FileStream(path,FileMode.Open,FileAccess.ReadWrite);
                    byte[] buff = new byte[fs.Length+1];
                    fs.Read(buff,0,(int)fs.Length);
                    buff[buff.Length-1] = 0;
                    fs.Close();
                    File.Delete(path);
                 
                    string BinPath = path.Substring(0,path.LastIndexOf('.'))+".bytes";
     //             FileStream cfs = new FileStream(BinPath,FileMode.Create);
                    cfs.Write(buff,0,buff.Length);
                    buff =null;
                    cfs.Close();
                     
    //              string AssetsPath = BinPath.Substring(BinPath.IndexOf("Assets"));
    //              Object ta = AssetDatabase.LoadAssetAtPath(AssetsPath,typeof(Object));
    //              BuildPipeline.BuildAssetBundle(ta, null, path);
                }
            }
            [MenuItem("Assets/Build AssetBundle From Selection - No dependency tracking")]
            static void ExportResourceNoTrack () {
                // Bring up save panel
                string path = EditorUtility.SaveFilePanel ("Save Resource", "", "New Resource", "unity3d");
                if (path.Length != 0) {
                    // Build the resource file from the active selection.
                    BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path);
                }
            }
             
         

      把打包的文件转换成了binary文件并多加了一个字节加密。

      当bytes文件生成好后再选中它,使用"Assets/Build AssetBundle From Selection - No dependency tracking"再次打包。

    using UnityEngine;
    using System.Collections;
    using System;
    
    public class WWWLoadTest : MonoBehaviour
    {
    
        public string BundleURL;
        public string AssetName;
        IEnumerator Start()
        {
              WWW www =WWW.LoadFromCacheOrDownload(BundleURL,2);
            
            yield return www;
            
            TextAsset txt = www.assetBundle.Load("characters",typeof(TextAsset)) as TextAsset;
            
            byte[]  data = txt.bytes;
            
            byte[] decryptedData = Decryption(data);
            Debug.LogError("decryptedData length:"+decryptedData.Length);
            StartCoroutine(LoadBundle(decryptedData));
        }
        
        IEnumerator LoadBundle(byte[] decryptedData){        
            AssetBundleCreateRequest acr = AssetBundle.CreateFromMemory(decryptedData);            
            yield return acr;
            AssetBundle bundle = acr.assetBundle;        
            Instantiate(bundle.Load(AssetName));
            
        }
        
        byte[] Decryption(byte[] data){
            byte[] tmp = new byte[data.Length-1];
            for(int i=0;i<data.Length-1;i++){
                tmp[i] = data[i];    
            }
            return tmp;
            
        }
    
        
    }

    WWW.LoadFromCacheOrDownload的作用就是下载并缓存资源,要注意后面的版本号参数,如果替换了资源却没有更新版本号,客户端依然会加载缓存中的文件。

    www.assetBundle.Load("characters",typeof(TextAsset)) as TextAsset  //characters是加密文件的名字

    AssetBundleCreateRequest acr = AssetBundle.CreateFromMemory(decryptedData);           

    这句是官网最坑爹的,AssetBundle.CreateFromMemory明 明返回的是AssetBundleCreateRequest官网却写得是AssetBundle,而且 AssetBundleCreateRequest是一个异步加载,必须用协程的方式加载官网也没有提到。跟多兄弟就倒在了这里

    完。

    原理这里要说明下,是这样子的,先把资源变成。unity3d格式,然后转成。bytes格式,再转成。unity3d格式,

    加载的时候加载。unity3d格式,解析,然后变资源

    我经过测试给出我的代码:

    using UnityEngine;
    using System.Collections;
    using UnityEditor;
    using System.IO;
    
    public class assetPack : Editor
    {
    //打包单个
    [MenuItem("Custom Editor/Create AssetBunldes Main")]
    static void CreateAssetBunldesMain ()
    {
        //获取在Project视图中选择的所有游戏对象
        Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
    
    //遍历所有的游戏对象
        foreach (Object obj in SelectedAsset)
        {
        //本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径
        //StreamingAssets是只读路径,不能写入
        //服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。
        string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle";
        if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)) {
        Debug.Log(obj.name +"资源打包成功");
        }
        else
        {
        Debug.Log(obj.name +"资源打包失败");
        }
        }
        //刷新编辑器
        AssetDatabase.Refresh ();  
     
    }
     
    [MenuItem("Custom Editor/Create AssetBunldes ALL")]
    static void CreateAssetBunldesALL ()
    {
     
        Caching.CleanCache ();
    
     
        string Path = Application.dataPath + "/StreamingAssets/ALL.assetbundle";
    
    
        Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
     
        foreach (Object obj in SelectedAsset)
        {
            Debug.Log ("Create AssetBunldes name :" + obj);
        }
    
            //这里注意第二个参数就行
            if (BuildPipeline.BuildAssetBundle (null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies)) {
            AssetDatabase.Refresh ();
        } else
        {
     
        }
    }
    
    [MenuItem("Custom Editor/Create Scene")]
    static void CreateSceneALL ()
    {
        //清空一下缓存
        Caching.CleanCache();
        string Path = Application.dataPath + "/eScene.unity3d";
        string[] levels = { "Assets/myScene.unity" };
        //打包场景
        BuildPipeline.BuildPlayer( levels, Path,BuildTarget.StandaloneWindows, BuildOptions.BuildAdditionalStreamedScenes);
        AssetDatabase.Refresh ();
    }
    
    [MenuItem("Custom Editor/Save Scene")]
    static void ExportScene()
    {
        // 打开保存面板,获得用户选择的路径  
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
    
        if (path.Length != 0)
        {
            // 选择的要保存的对象  
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            string[] scenes = { "Assets/myScene.unity" };
            //打包  
            BuildPipeline.BuildPlayer(scenes, path, BuildTarget.StandaloneWindows, BuildOptions.BuildAdditionalStreamedScenes);
        }
        AssetDatabase.Refresh();
    }
    [MenuItem("Custom Editor/Save Scene2")]
    static void ExportResource()
    {
        // Bring up save panel
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
        if (path.Length != 0)
        {
            // Build the resource file from the active selection.
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
                              BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets);
            Selection.objects = selection;
        }
    }
    
    [MenuItem("Custom Editor/Build AssetBundle From Selection - Track dependencies")]
    static void ExportResource2()
    {
        // Bring up save panel
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
        if (path.Length != 0)
        {
            // Build the resource file from the active selection.
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
                              BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets);
            Selection.objects = selection;
        }
    }
    
    [MenuItem("Custom Editor/Build AssetBundle Complited  to  bytes")]
    static void ExportResource5()
    {
        // Bring up save panel
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
        if (path.Length != 0)
        {
            // Build the resource file from the active selection.
            Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
            BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path,
                              BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows);
            Selection.objects = selection;
    
    
            FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite);
            byte[] buff = new byte[fs.Length + 1];
            fs.Read(buff, 0, (int)fs.Length);
            buff[buff.Length - 1] = 0;
            Debug.Log("filelength:"+ buff.Length);
            fs.Close();
            File.Delete(path);
    
            string BinPath = path.Substring(0, path.LastIndexOf('.')) + ".bytes";
            FileStream cfs = new FileStream(BinPath,FileMode.Create);
            cfs.Write(buff, 0, buff.Length);
            Debug.Log("filelength:" + buff.Length);
            buff = null;
            cfs.Close();
     
        }
    }
    
    [MenuItem("Custom Editor/Build AssetBundle From Selection Twice")]
    static void ExportResourceNoTrack()
    {
        // Bring up save panel
        string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d");
        if (path.Length != 0)
        {
            // Build the resource file from the active selection.
            BuildPipeline.BuildAssetBundle(Selection.activeObject, Selection.objects, path);
        }
    }
    }

    加载部分

    using UnityEngine;
    using System.Collections;
    
    public class loadnew : MonoBehaviour 
    {
        public string filename;
        private string BundleURL;
        private string AssetName;
        IEnumerator Start()
        {
            BundleURL = "file://" + Application.dataPath +"/"+ filename+".unity3d";
            Debug.Log("path:"+ BundleURL);
            WWW m_Download = new WWW(BundleURL);
    
            yield return m_Download;
            if (m_Download.error != null)
            {
                //   Debug.LogError(m_Download.error);
                Debug.Log("Warning errow: " + "NewScene");
                yield break;
            }
    
            TextAsset txt = m_Download.assetBundle.Load(filename, typeof(TextAsset)) as TextAsset;
            byte[] data = txt.bytes;
    
            byte[] decryptedData = Decryption(data);
            Debug.Log("decryptedData length:" + decryptedData.Length);
            StartCoroutine(LoadBundle(decryptedData));
        }
    
        IEnumerator LoadBundle(byte[] decryptedData)
        {
            AssetBundleCreateRequest acr = AssetBundle.CreateFromMemory(decryptedData);
            yield return acr;
            AssetBundle bundle = acr.assetBundle;
            Instantiate(bundle.mainAsset);
    
        }
    
        byte[] Decryption(byte[] data)
        {
            byte[] tmp = new byte[data.Length - 1];
            for (int i = 0; i < data.Length - 1; i++)
            {
                tmp[i] = data[i];
            }
            return tmp;
    
        }
    
        void update()
        {
    
        }
    }
  • 相关阅读:
    ZOJ 3332 Strange Country II
    ZOJ 3331 Process the Tasks(双塔DP)
    ZOJ 3326 An Awful Problem(模拟)
    HDU 1796 How many integers can you find(容斥原理)
    HDU 4059 The Boss on Mars(容斥原理)
    HDU 4135 Co-prime(容斥原理)
    HDU 5677 ztr loves substring(回文串加多重背包)
    CodeForces 668B Little Artem and Dance
    CodeForces 667A Pouring Rain
    Java实现 LeetCode 764 最大加号标志(暴力递推)
  • 原文地址:https://www.cnblogs.com/dragon2012/p/3894695.html
Copyright © 2011-2022 走看看