├── unity ├── ProjectSettings │ ├── ProjectVersion.txt │ ├── TagManager.asset │ ├── TimeManager.asset │ ├── AudioManager.asset │ ├── InputManager.asset │ ├── NavMeshAreas.asset │ ├── DynamicsManager.asset │ ├── EditorSettings.asset │ ├── GraphicsSettings.asset │ ├── NetworkManager.asset │ ├── ProjectSettings.asset │ ├── QualitySettings.asset │ ├── UnityAdsSettings.asset │ ├── Physics2DSettings.asset │ ├── ClusterInputManager.asset │ ├── EditorBuildSettings.asset │ └── UnityConnectSettings.asset └── Assets │ ├── Example │ ├── 3336.mat │ ├── 3336.png │ ├── Cube.prefab │ ├── Example.unity │ ├── Sphere.prefab │ ├── Materials │ │ ├── 3336.mat │ │ └── 3336.mat.meta │ ├── 3336.mat.meta │ ├── Example.unity.meta │ ├── Cube.prefab.meta │ ├── Sphere.prefab.meta │ ├── Materials.meta │ ├── Example1.cs.meta │ ├── Example2.cs.meta │ ├── 3336.png.meta │ ├── Example1.cs │ └── Example2.cs │ ├── Example.meta │ ├── Script.meta │ └── Script │ ├── Core.meta │ └── Core │ ├── AssetBundle.meta │ ├── AssetBundle │ ├── Editor.meta │ ├── FileLocalMgr.cs.meta │ ├── AssetBundleMgr.cs.meta │ ├── FileUpdateMgr.cs.meta │ ├── AssetBundleUtility.cs.meta │ ├── Editor │ │ ├── AssetBundleBuilder.cs.meta │ │ └── AssetBundleBuilder.cs │ ├── FileLocalMgr.cs │ ├── AssetBundleMgr.cs │ ├── FileUpdateMgr.cs │ └── AssetBundleUtility.cs │ ├── IOManager.cs.meta │ ├── ResourceMgr.cs.meta │ ├── WWWLoader.cs.meta │ ├── WWWLoader.cs │ ├── ResourceMgr.cs │ └── IOManager.cs └── README.md /unity/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 5.3.1f1 2 | m_StandardAssetsVersion: 0 3 | -------------------------------------------------------------------------------- /unity/Assets/Example/3336.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/Assets/Example/3336.mat -------------------------------------------------------------------------------- /unity/Assets/Example/3336.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/Assets/Example/3336.png -------------------------------------------------------------------------------- /unity/Assets/Example/Cube.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/Assets/Example/Cube.prefab -------------------------------------------------------------------------------- /unity/Assets/Example/Example.unity: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/Assets/Example/Example.unity -------------------------------------------------------------------------------- /unity/Assets/Example/Sphere.prefab: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/Assets/Example/Sphere.prefab -------------------------------------------------------------------------------- /unity/Assets/Example/Materials/3336.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/Assets/Example/Materials/3336.mat -------------------------------------------------------------------------------- /unity/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/TagManager.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/TimeManager.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/AudioManager.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/InputManager.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/NavMeshAreas.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/DynamicsManager.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/EditorSettings.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/GraphicsSettings.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/NetworkManager.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/ProjectSettings.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/QualitySettings.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/UnityAdsSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/UnityAdsSettings.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/Physics2DSettings.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/ClusterInputManager.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/EditorBuildSettings.asset -------------------------------------------------------------------------------- /unity/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hiram3512/HiAssetBundle_unity/HEAD/unity/ProjectSettings/UnityConnectSettings.asset -------------------------------------------------------------------------------- /unity/Assets/Example/3336.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 34028e9126afaa242ae0ef3c978cfa0a 3 | timeCreated: 1453267881 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /unity/Assets/Example/Example.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 385f2af4492708e4f943e2bb58c08db8 3 | timeCreated: 1453260920 4 | licenseType: Pro 5 | DefaultImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /unity/Assets/Example.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a9cc7319c987e484694c8d28208369b2 3 | folderAsset: yes 4 | timeCreated: 1465810574 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /unity/Assets/Example/Cube.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e90550356932ab0469ff387f91afdee6 3 | timeCreated: 1453260905 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: test 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /unity/Assets/Example/Materials/3336.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b37d0b7d5ca301841875836f218ba0df 3 | timeCreated: 1453277961 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /unity/Assets/Example/Sphere.prefab.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55afa040cfd217c49a8ea9300db21d26 3 | timeCreated: 1453277965 4 | licenseType: Pro 5 | NativeFormatImporter: 6 | userData: 7 | assetBundleName: test2 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /unity/Assets/Script.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1ddc772ab9d72734f986b00d64e711de 3 | folderAsset: yes 4 | timeCreated: 1465810574 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e463eba9f0c23584a9ae8bba08d33d46 3 | folderAsset: yes 4 | timeCreated: 1456911319 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /unity/Assets/Example/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: bc0d0482c827bd44486c3dfd6c983650 3 | folderAsset: yes 4 | timeCreated: 1453277961 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d9eafd95b7e35c44da6f4895d36702ce 3 | folderAsset: yes 4 | timeCreated: 1455879238 5 | licenseType: Free 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fdd36f4e09c4e5e46b81918940bb01fb 3 | folderAsset: yes 4 | timeCreated: 1452764964 5 | licenseType: Pro 6 | DefaultImporter: 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /unity/Assets/Example/Example1.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 67c20337f8f2c9c469ea2cc7a93b1630 3 | timeCreated: 1456988090 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/IOManager.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e0e7f16dd98be174980381a280d6fbd2 3 | timeCreated: 1456987795 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/ResourceMgr.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b366ba4e4365bfd46825c4216904ea8f 3 | timeCreated: 1462247316 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Example/Example2.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: da5e29bb601f8ca4aa0d73c43089e9ec 3 | timeCreated: 1453275219 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/WWWLoader.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: b44339657a1b3314fb80e30ad9542676 3 | timeCreated: 1455532094 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/FileLocalMgr.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 375e92e5627568d438fcefa13220a608 3 | timeCreated: 1456911209 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/AssetBundleMgr.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: face74c38e0619a4f9c6314d05f89632 3 | timeCreated: 1453271355 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/FileUpdateMgr.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1c8c13d6f1a708848ae34b11ee6e1016 3 | timeCreated: 1452779174 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/AssetBundleUtility.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: cae6407ce98418f42a31a8831e0e2079 3 | timeCreated: 1455606197 4 | licenseType: Free 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/Editor/AssetBundleBuilder.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0b3106ec9cabdd248bb99cdef46976a6 3 | timeCreated: 1452764964 4 | licenseType: Pro 5 | MonoImporter: 6 | serializedVersion: 2 7 | defaultReferences: [] 8 | executionOrder: 0 9 | icon: {instanceID: 0} 10 | userData: 11 | assetBundleName: 12 | assetBundleVariant: 13 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/WWWLoader.cs: -------------------------------------------------------------------------------- 1 | //**************************************************************************** 2 | // Description: 3 | // Author: hiramtan@qq.com 4 | //**************************************************************************** 5 | using UnityEngine; 6 | using System.Collections; 7 | using System; 8 | 9 | public class WWWLoader : MonoBehaviour 10 | { 11 | private static WWWLoader instance; 12 | public static WWWLoader Instance 13 | { 14 | get 15 | { 16 | if (instance == null) 17 | instance = new GameObject("WWWLoader").AddComponent(); 18 | return instance; 19 | } 20 | } 21 | public void Startload(string downloadUrl, Action callBackHandler = null) 22 | { 23 | lock(this) 24 | { 25 | StartCoroutine(Load(downloadUrl, callBackHandler)); 26 | } 27 | } 28 | private IEnumerator Load(string downloadUrl, Action callBackHandler) 29 | { 30 | WWW www = new WWW(downloadUrl); 31 | while (!www.isDone) 32 | yield return www; 33 | if (callBackHandler != null) 34 | callBackHandler(www); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /unity/Assets/Example/3336.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04d6d2480fe27554b8b9a7a916d3ce2a 3 | timeCreated: 1453260833 4 | licenseType: Pro 5 | TextureImporter: 6 | fileIDToRecycleName: {} 7 | serializedVersion: 2 8 | mipmaps: 9 | mipMapMode: 0 10 | enableMipMap: 1 11 | linearTexture: 0 12 | correctGamma: 0 13 | fadeOut: 0 14 | borderMipMap: 0 15 | mipMapFadeDistanceStart: 1 16 | mipMapFadeDistanceEnd: 3 17 | bumpmap: 18 | convertToNormalMap: 0 19 | externalNormalMap: 0 20 | heightScale: .25 21 | normalMapFilter: 0 22 | isReadable: 0 23 | grayScaleToAlpha: 0 24 | generateCubemap: 0 25 | cubemapConvolution: 0 26 | cubemapConvolutionSteps: 8 27 | cubemapConvolutionExponent: 1.5 28 | seamlessCubemap: 0 29 | textureFormat: -1 30 | maxTextureSize: 2048 31 | textureSettings: 32 | filterMode: -1 33 | aniso: -1 34 | mipBias: -1 35 | wrapMode: -1 36 | nPOTScale: 1 37 | lightmap: 0 38 | rGBM: 0 39 | compressionQuality: 50 40 | spriteMode: 0 41 | spriteExtrude: 1 42 | spriteMeshType: 1 43 | alignment: 0 44 | spritePivot: {x: .5, y: .5} 45 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 46 | spritePixelsToUnits: 100 47 | alphaIsTransparency: 0 48 | textureType: -1 49 | buildTargetSettings: [] 50 | spriteSheet: 51 | sprites: [] 52 | spritePackingTag: 53 | userData: 54 | assetBundleName: common 55 | assetBundleVariant: 56 | -------------------------------------------------------------------------------- /unity/Assets/Example/Example1.cs: -------------------------------------------------------------------------------- 1 | //**************************************************************************** 2 | // Description:资源维护 3 | // 1.将跟包资源复制到沙盒目录下(可以扩展压缩/解压缩,比如跟包资源是压缩包) 4 | // 2.检查本地需要更新的文件列表并提示玩家需要更新xx兆资源 5 | // 3.开始更新资源服务器上的最新资源 6 | // 4.更新完成后执行回调方法(可以扩展后续逻辑,比如更新完成后开始登陆) 7 | // 8 | //ps.所有示例逻辑会把streamingAssetsPath当做服务器资源地址,模拟从服务器下载过程.真正需要从服务器下载时使用注释的代码. 9 | // 10 | // Author: hiramtan@qq.com 11 | //**************************************************************************** 12 | using UnityEngine; 13 | using System.Collections; 14 | using HiAssetBundle; 15 | 16 | 17 | public class Example1 : MonoBehaviour 18 | { 19 | 20 | // Use this for initialization 21 | void Start() 22 | { 23 | CopyFileFromAppToPersistentFolder(); 24 | } 25 | 26 | void CopyFileFromAppToPersistentFolder() 27 | { 28 | FileLocalMgr mgr = new FileLocalMgr(); 29 | mgr.Init(CopyFinish); 30 | } 31 | void CopyFinish() 32 | { 33 | //复制结束 34 | 35 | //检查网络更新资源 36 | CheckHowManyFileNeedUpdate(); 37 | } 38 | void CheckHowManyFileNeedUpdate() 39 | { 40 | FileUpdateMgr mgr = new FileUpdateMgr(); 41 | mgr.Init_OnlyForTest(CheckFinish); 42 | // mgr.Init("url",CheckFinish); 43 | } 44 | void CheckFinish(float param) 45 | { 46 | Debug.Log(string.Format("you should download: {0}M", param)); 47 | FileUpdateMgr mgr = new FileUpdateMgr(); 48 | mgr.StartUpdate(DownloadFinish); 49 | } 50 | void DownloadFinish() 51 | { 52 | Debug.Log("download finish"); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/ResourceMgr.cs: -------------------------------------------------------------------------------- 1 | //********************************************************************* 2 | // Description: 3 | // Author: hiramtan@qq.com 4 | //********************************************************************* 5 | using UnityEngine; 6 | using System.Collections; 7 | using HiAssetBundle; 8 | #if UNITY_EDITOR 9 | using UnityEditor; 10 | #endif 11 | 12 | 13 | public class ResourceMgr 14 | { 15 | 16 | private static ResourceMgr instance; 17 | public static ResourceMgr Instance 18 | { 19 | get 20 | { 21 | if (instance == null) 22 | instance = new ResourceMgr(); 23 | return instance; 24 | } 25 | } 26 | /// 27 | /// Important: paramName must include extension, for example "tank.prefab" 28 | /// 29 | /// 30 | /// 31 | /// 32 | public T GetObj(string param) where T:UnityEngine.Object 33 | { 34 | int tempIndex = param.LastIndexOf("__"); 35 | string paramFolder = param.Substring(0, tempIndex); 36 | paramFolder = paramFolder.Replace("__", "/"); 37 | string paramName = param.Substring(tempIndex + 1); 38 | #if UNITY_EDITOR 39 | var temp = "Assets/" + paramFolder + "/" + paramName; 40 | return AssetDatabase.LoadAssetAtPath(temp); 41 | #endif 42 | paramFolder = paramFolder.Replace("/", ""); 43 | paramFolder = paramFolder.ToLower(); 44 | paramName = paramName.Remove(paramName.LastIndexOf(".")); 45 | paramName = paramName.ToLower(); 46 | AssetBundle tempAB = AssetBundleMgr.GetAssetBundle(paramFolder); 47 | if (tempAB != null && tempAB.Contains(paramName)) 48 | return tempAB.LoadAsset(paramName); 49 | Debug.LogError("the things you want to load is null"); 50 | return null; 51 | } 52 | 53 | public GameObject GetGameObject(string param) 54 | { 55 | Object temp = GetObj(param); 56 | if (temp != null) 57 | return (GameObject)MonoBehaviour.Instantiate(temp); 58 | return null; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /unity/Assets/Example/Example2.cs: -------------------------------------------------------------------------------- 1 | //**************************************************************************** 2 | // Description:资源加载与卸载 3 | // 保证资源在内存中只有一份 4 | // 1.加载资源时会自动加载所有依赖的资源(当被依赖的资源已经被加载时则不必再次加载;若没有加载过则加载依赖资源) 5 | // 2.卸载资源时会自动卸载所有依赖的资源(当被依赖的资源还被其他资源依赖时不能卸载;若被依赖的资源没有被任何资源依赖时则卸载) 6 | // 7 | //ps.所有示例逻辑会把streamingAssetsPath当做服务器资源地址,模拟从服务器下载过程.真正需要从服务器下载时使用注释的代码. 8 | // 9 | // Author: hiramtan@qq.com 10 | //**************************************************************************** 11 | 12 | using HiAssetBundle; 13 | using UnityEngine; 14 | 15 | public class Example2 : MonoBehaviour 16 | { 17 | FileUpdateMgr mgr = new FileUpdateMgr(); 18 | // Use this for initialization 19 | void Start() 20 | { 21 | mgr.Init_OnlyForTest(CheckFinish); 22 | 23 | 24 | //string url = ""; 25 | //mgr.Init(url, FinishDownload); 26 | 27 | } 28 | 29 | void CheckFinish(float param) 30 | { 31 | Debug.Log("should download:" + param); 32 | mgr.StartUpdate(UpdateFinish); 33 | } 34 | void UpdateFinish() 35 | { 36 | Debug.Log("download finish"); 37 | } 38 | // Update is called once per frame 39 | void Update() 40 | { 41 | //for test:展示下载进度 42 | if (mgr != null && mgr.needUpdate) 43 | Debug.Log(mgr.progress); 44 | } 45 | 46 | void OnGUI() 47 | { 48 | //if can destroy dependence asset 49 | if (GUI.Button(new Rect(0, 0, 100, 40), "Clean Common")) 50 | { 51 | AssetBundleMgr.UnLoadAssetBundle("common"); 52 | } 53 | //still can't destroy dependence asset 54 | if (GUI.Button(new Rect(0, 50, 100, 40), "Clean test")) 55 | { 56 | AssetBundleMgr.UnLoadAssetBundle("test"); 57 | } 58 | //destroy "test2", also destroy destroy dependence 59 | if (GUI.Button(new Rect(0, 100, 100, 40), "Clean test2")) 60 | { 61 | AssetBundleMgr.UnLoadAssetBundle("test2"); 62 | } 63 | if (GUI.Button(new Rect(0, 150, 100, 40), "load")) 64 | { 65 | AssetBundle t1 = AssetBundleMgr.GetAssetBundle("test"); 66 | Object cube = t1.LoadAsset("Cube"); 67 | GameObject go = Instantiate(cube) as GameObject; 68 | go.transform.position = Vector3.left; 69 | 70 | AssetBundle t2 = AssetBundleMgr.GetAssetBundle("test2"); 71 | Object sphere = t2.LoadAsset("sphere"); 72 | Instantiate(sphere); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HiAssetBundle_unity 2 | =================== 3 | 4 | 开源地址:[https://github.com/hiramtan/HiAssetBundle_unity](https://github.com/hiramtan/HiAssetBundle_unity "Title") 5 | 6 | Unity中的热更新逻辑,Web服务器放置一份完整asset bundle资源,自动维护本地资源与服务器一致。 7 | 8 | 9 | ---------- 10 | **功能说明:** 11 | 12 | > - 资源重命名(鼠标选在文件夹,点击编辑器菜单下的重命名按钮,会重命名该文件夹下的所有文件) 13 | > - 快速设置AssetBundle的包名(点击文件夹,会自动把该文件夹下资源的ab的包名设置为文件夹的名字) 14 | > - 打包Assetbundle资源包(支持windows/android/ios) 15 | > - 资源统一加载逻辑(只需要传入文件名就能从对应的assetbundle中加载对应的文件) 16 | > - 资源在内存中的释放 17 | > - 跟包资源(打包到手机安装包的资源)解压到可读写目录 18 | > - 提示需要下载XX兆更新,确定下载吗? 19 | > - 下载服务器最新资源(热更),保持本地资源与服务器资源一致 20 | 21 | ---------- 22 | **详细说明:** 23 | > - 资源重命名后会包含路径信息,为以后assetbundle加载资源方便(不需要在提供包名+文件名) 24 | > - 编辑器模式下使用AssetDatabase方式加载资源(为方便快速开发迭代) 25 | > - 编辑器菜单的assetbundle命名只是傻瓜式命名(以每个prefab的文件夹作为包名),需要将公共资源设置到统一的assetbundle中 26 | > - 打包逻辑默认采用非压缩方式,可手动修改源码改为其他方式 27 | > - 打包逻辑会将生成的assetbundle文件放置到StreamingAsset目录下(方便初始化运行时复制资源) 28 | > - 打包逻辑主要分unity引擎维护部分(处理依赖关系)和其他部分(文本文件,数据库文件,二进制文件等) 29 | > - 哈希文件: 30 | > - 执行打包逻辑会生成哈希列表,包含哈希值,文件存储目录,文件大小. 31 | > - 通过获取哈希列表中的文件大小能够实现: "您有10M资源要更新,需要现在更新吗" 32 | > - 通过哈希文件比对能获得所要更新的文件数量和进度条:"您正在更新第5个文件" 33 | > - 一共有100个文件需要更新,当更新到第50个时网络断开,下次继续从第51个开始更新 34 | > - 资源加载提供接口,会通过传入的文件名解析获得相应的资源(编辑器下直接获取,非编辑器从assetbundle中获取) 35 | > - 初始化时会自动启动资源依赖关系处理逻辑,加载物体会加载依赖的资源,卸载物体会卸载依赖的资源(如果依赖资源未被其他资源依赖进行卸载,如果被其他资源依赖,继续在内存中) 36 | > - 提供接口主动卸载assetbundle在内存中的占用 37 | 38 | ---------- 39 | **操作流程:** 40 | > - 编辑器模式下(方便测试) 41 | > - 点击build assetbundle window 42 | > - 运行unity即可 43 | > - 非编辑器模式(正式流程) 44 | > - 设置文件名(编辑器已提供按钮) 45 | > - 设置assetbundle包名(编辑器已提供按钮) 46 | > - 点击build assetbundle android(选择自己对应的平台) 47 | > - 发布apk,ipa文件 48 | 49 | ---------- 50 | **逻辑执行流程:** 51 | > - 将跟包资源(安装包中的资源)复制到可读写目录下 52 | > - 复制完成开始比对哈希文件,开始更新资源 53 | > - 下载最添加资源,替换旧资源,删除原来可读写目录下的无用资源 54 | > - 初始化assetbundle依赖关系 55 | > - 完成整个流程 56 | 57 | ---------- 58 | **逻辑热更篇:** 59 | > - 无论是L#更新dll还是使用ulua,tolua,slua更新.lua文件都可以当做是资源文件处理. 60 | > - 能成功下载到最新的.dll或.lua,热更实现参照对应的官网文档. 61 | 62 | ---------- 63 | > **Note:** 64 | 65 | > - 文件/文件夹命名严禁包含空格(逻辑自动删除文件/文件夹名字中的空格) 66 | 67 | > - 从网络加载资源时下载资源的url由目录地址和相对路径拼接而成,比如http://192.168.1.1/new test.txt如果用www直接访问这个地址是访问不到的.需要访问http://192.168.1.1/new%20test.txt才能访问到.%20是html的空格编码. 68 | 69 | > - 访问本地streamingasset目录时,比如streamasset/new test.txt直接访问这个地址就可以了.为了保证一致,删除所有空格 70 | > - 注意unix系统(android/ios)的大小写敏感问题 71 | 72 | 点击链接加入QQ群【83596104】:https://jq.qq.com/?_wv=1027&k=5l6rZEr 73 | 74 | support: hiramtan@live.com 75 | 76 | *********** 77 | 78 | MIT License 79 | 80 | Copyright (c) [2017] [Hiram] 81 | 82 | Permission is hereby granted, free of charge, to any person obtaining a copy 83 | of this software and associated documentation files (the "Software"), to deal 84 | in the Software without restriction, including without limitation the rights 85 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 86 | copies of the Software, and to permit persons to whom the Software is 87 | furnished to do so, subject to the following conditions: 88 | 89 | The above copyright notice and this permission notice shall be included in all 90 | copies or substantial portions of the Software. 91 | 92 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 93 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 94 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 95 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 96 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 97 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 98 | SOFTWARE. 99 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/FileLocalMgr.cs: -------------------------------------------------------------------------------- 1 | //**************************************************************************** 2 | // Description: 3 | // Author: hiramtan@qq.com 4 | //**************************************************************************** 5 | using HiIO; 6 | using System; 7 | using System.Collections; 8 | using System.IO; 9 | using UnityEngine; 10 | 11 | namespace HiAssetBundle 12 | { 13 | public class FileLocalMgr 14 | { 15 | public float progress { get; private set; } 16 | private Action handler; 17 | private byte[] fileInfoBytes; 18 | private string[] lines; 19 | private int index; 20 | private string fileOutPutPath; 21 | public void Init(Action param) 22 | { 23 | handler = param; 24 | string filePath = AssetBundleUtility.GetFileFolder() + "/" + AssetBundleUtility.fileName; 25 | if (File.Exists(filePath)) 26 | handler(); 27 | else 28 | { 29 | DeleteFileFolder(); 30 | GetFileInfo(); 31 | } 32 | } 33 | void GetFileInfo() 34 | { 35 | string filePath = AssetBundleUtility.fileFolderName + "/" + AssetBundleUtility.fileName; 36 | IOManager.Instance.ReadFileFromStreamingAssetsPath(filePath, GetFileInfoFinish); 37 | } 38 | 39 | void GetFileInfoFinish(WWW param) 40 | { 41 | if (param.text.Length > 0) 42 | { 43 | fileInfoBytes = param.bytes; 44 | lines = param.text.Split(new char[] { '\r', '\n' }); 45 | GetFile(); 46 | } 47 | else 48 | handler(); 49 | } 50 | void GetFile() 51 | { 52 | progress = (float)index / lines.Length; 53 | if (lines.Length > index) 54 | { 55 | if (string.IsNullOrEmpty(lines[index])) { index++; GetFile(); } 56 | else 57 | { 58 | string[] keyValue = lines[index].Split('|'); 59 | string fileName = keyValue[1].Trim(); 60 | string filePath = AssetBundleUtility.fileFolderName + "/" + fileName; 61 | fileOutPutPath = AssetBundleUtility.GetFileFolder() + "/" + fileName; 62 | IOManager.Instance.ReadFileFromStreamingAssetsPath(filePath, GetFileFinish); 63 | } 64 | } 65 | else 66 | { 67 | string path = AssetBundleUtility.fileFolderName + "/" + AssetBundleUtility.fileName; 68 | IOManager.Instance.WriteFileToPersistentDataPath(path, fileInfoBytes); 69 | handler(); 70 | } 71 | } 72 | void GetFileFinish(WWW param) 73 | { 74 | index++; 75 | IOManager.Instance.WriteFile(fileOutPutPath, param.bytes); 76 | GetFile(); 77 | } 78 | void DeleteFileFolder() 79 | { 80 | string tempD = AssetBundleUtility.GetFileFolder(); 81 | //if (!Directory.Exists(tempD)) 82 | // return; 83 | //DirectoryInfo tempDInfo = new DirectoryInfo(tempD); 84 | //FileInfo[] tempFInfos = tempDInfo.GetFiles("*.*", SearchOption.AllDirectories); 85 | //for (int i = 0; i < tempFInfos.Length; i++) 86 | // if (File.Exists(tempFInfos[i].Name)) 87 | // File.Delete(tempFInfos[i].Name); 88 | if (Directory.Exists(tempD)) 89 | Directory.Delete(tempD, true); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /unity/Assets/Script/Core/IOManager.cs: -------------------------------------------------------------------------------- 1 | //**************************************************************************** 2 | // Description: 文件常用操作 3 | // Author: hiramtan@qq.com 4 | //**************************************************************************** 5 | using System; 6 | using System.IO; 7 | using UnityEngine; 8 | using System.Collections; 9 | namespace HiIO 10 | { 11 | public class IOManager 12 | { 13 | private static IOManager instance; 14 | public static IOManager Instance 15 | { 16 | get 17 | { 18 | if (instance == null) 19 | instance = new IOManager(); 20 | return instance; 21 | } 22 | } 23 | public bool IsFolderExist(string param) 24 | { 25 | return Directory.Exists(param); 26 | } 27 | 28 | public void CreateFolder(string param) 29 | { 30 | Directory.CreateDirectory(param); 31 | } 32 | 33 | public void DeleteFolder(string param) 34 | { 35 | Directory.Delete(param, true);//第二个参数:删除子目录 36 | } 37 | 38 | public bool IsFileExist(string param) 39 | { 40 | return File.Exists(param); 41 | } 42 | Action finishLoadFromStreamingAssetsPathHandler; 43 | public void ReadFileFromStreamingAssetsPath(string paramPath, Action paramHandler) 44 | { 45 | finishLoadFromStreamingAssetsPathHandler = paramHandler; 46 | paramPath = GetStreamingAssetsPath() + "/" + paramPath; 47 | WWWLoader.Instance.Startload(paramPath, FinishLoadFromStreamingAssetsPath); 48 | } 49 | private void FinishLoadFromStreamingAssetsPath(WWW paramWWW) 50 | { 51 | finishLoadFromStreamingAssetsPathHandler(paramWWW); 52 | } 53 | 54 | public byte[] ReadFileFromPersistentDataPath(string param) 55 | { 56 | param = Application.persistentDataPath + "/" + param; 57 | return ReadFile(param); 58 | } 59 | public byte[] ReadFile(string param) 60 | { 61 | try 62 | { 63 | using (FileStream fs = new FileStream(param, FileMode.Open, FileAccess.Read)) 64 | { 65 | byte[] bytes = new byte[fs.Length]; 66 | fs.Read(bytes, 0, (int)fs.Length); 67 | return bytes; 68 | } 69 | } 70 | catch (Exception e) 71 | { 72 | Debug.Log(e.ToString()); 73 | } 74 | return null; 75 | } 76 | public void WriteFileToPersistentDataPath(string paramPath, byte[] paramBytes) 77 | { 78 | paramPath = Application.persistentDataPath + "/" + paramPath; 79 | WriteFile(paramPath, paramBytes); 80 | } 81 | public void WriteFile(string paramPath, byte[] paramBytes) 82 | { 83 | try 84 | { 85 | string directory = Path.GetDirectoryName(paramPath); 86 | if (!Directory.Exists(directory)) 87 | Directory.CreateDirectory(directory); 88 | using (FileStream fs = new FileStream(paramPath, FileMode.Create, FileAccess.Write)) 89 | { 90 | fs.Write(paramBytes, 0, paramBytes.Length); 91 | } 92 | } 93 | catch (Exception e) 94 | { 95 | Debug.Log(e.ToString()); 96 | } 97 | } 98 | public void DeleteFile(string param) 99 | { 100 | File.Delete(param); 101 | } 102 | private string GetStreamingAssetsPath() 103 | { 104 | # if UNITY_EDITOR || UNITY_IPHONE 105 | string path = "file://" + Application.streamingAssetsPath; 106 | #else 107 | string path = Application.streamingAssetsPath; 108 | #endif 109 | return path; 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/AssetBundleMgr.cs: -------------------------------------------------------------------------------- 1 | //********************************************************************* 2 | // Description: 3 | // Author: hiramtan@qq.com 4 | //********************************************************************* 5 | using System.Collections.Generic; 6 | using System.IO; 7 | using UnityEngine; 8 | 9 | namespace HiAssetBundle 10 | { 11 | public class AssetBundleMgr 12 | { 13 | private static Dictionary loadedAssetBundles = new Dictionary(); 14 | private static Dictionary assetBundleDependencies = new Dictionary(); 15 | 16 | public static void Init() 17 | { 18 | SetDependenceInfo(); 19 | } 20 | private static void SetDependenceInfo() 21 | { 22 | string path = AssetBundleUtility.GetManifestPath(); 23 | if (!File.Exists(path)) 24 | { 25 | Debug.LogError("can't find Manifest file"); 26 | return; 27 | } 28 | 29 | #if UNITY_5_3 || UNITY_5_3_OR_NEWER 30 | AssetBundle assetBundle = AssetBundle.LoadFromFile(path); 31 | #else 32 | AssetBundle assetBundle = AssetBundle.CreateFromFile(path); 33 | #endif 34 | AssetBundleManifest assetBundleManifest = assetBundle.LoadAsset("assetbundlemanifest") as AssetBundleManifest; 35 | string[] assetBundleNames = assetBundleManifest.GetAllAssetBundles(); 36 | foreach (string paramName in assetBundleNames) 37 | { 38 | string[] dependence = assetBundleManifest.GetAllDependencies(paramName); 39 | assetBundleDependencies.Add(paramName, dependence); 40 | } 41 | assetBundle.Unload(true); 42 | } 43 | 44 | public static AssetBundle GetAssetBundle(string paramName) 45 | { 46 | if (assetBundleDependencies.ContainsKey(paramName)) 47 | { 48 | string[] dependenceNames = assetBundleDependencies[paramName]; 49 | foreach (string paramdependenceName in dependenceNames) 50 | { 51 | if (loadedAssetBundles.ContainsKey(paramdependenceName)) 52 | loadedAssetBundles[paramdependenceName].dependenceCount++; 53 | else 54 | { 55 | string path = AssetBundleUtility.GetAssetBundleFolder() + "/" + paramdependenceName; 56 | if (File.Exists(path)) 57 | { 58 | #if UNITY_5_3 || UNITY_5_3_OR_NEWER 59 | AssetBundle ab = AssetBundle.LoadFromFile(path); 60 | #else 61 | AssetBundle ab = AssetBundle.CreateFromFile(path); 62 | #endif 63 | LoadedAssetBundle loadedAssetBundle = new LoadedAssetBundle(ab); 64 | loadedAssetBundles.Add(paramdependenceName, loadedAssetBundle); 65 | } 66 | else 67 | { 68 | Debug.LogError("can't find ab file"); 69 | } 70 | //AssetBundle ab = AssetBundle.LoadFromFile(path); 71 | //LoadedAssetBundle loadedAssetBundle = new LoadedAssetBundle(ab); 72 | //loadedAssetBundles.Add(paramdependenceName, loadedAssetBundle); 73 | } 74 | } 75 | } 76 | 77 | if (loadedAssetBundles.ContainsKey(paramName)) 78 | { 79 | loadedAssetBundles[paramName].dependenceCount++; 80 | return loadedAssetBundles[paramName].assetBundle; 81 | } 82 | { 83 | string assetBundlePath = AssetBundleUtility.GetAssetBundleFolder() + "/" + paramName; 84 | if (!File.Exists(assetBundlePath)) 85 | { 86 | Debug.LogError("file not exist"); 87 | return null; 88 | } 89 | 90 | #if UNITY_5_3 || UNITY_5_3_OR_NEWER 91 | AssetBundle assetBundle = AssetBundle.LoadFromFile(assetBundlePath); 92 | #else 93 | AssetBundle assetBundle = AssetBundle.CreateFromFile(assetBundlePath); 94 | #endif 95 | LoadedAssetBundle loadedAssetBundle = new LoadedAssetBundle(assetBundle); 96 | loadedAssetBundles.Add(paramName, loadedAssetBundle); 97 | return loadedAssetBundles[paramName].assetBundle; 98 | } 99 | 100 | } 101 | 102 | public static void UnLoadAssetBundle(string paramName) 103 | { 104 | if (assetBundleDependencies.ContainsKey(paramName)) 105 | { 106 | string[] dependenceNames = assetBundleDependencies[paramName]; 107 | foreach (string paramdependenceName in dependenceNames) 108 | { 109 | if (loadedAssetBundles.ContainsKey(paramdependenceName)) 110 | { 111 | loadedAssetBundles[paramdependenceName].dependenceCount--; 112 | if (loadedAssetBundles[paramdependenceName].dependenceCount == 0) 113 | { 114 | loadedAssetBundles[paramdependenceName].Unload(); 115 | loadedAssetBundles.Remove(paramdependenceName); 116 | } 117 | 118 | } 119 | } 120 | } 121 | if (loadedAssetBundles.ContainsKey(paramName)) 122 | { 123 | loadedAssetBundles[paramName].dependenceCount--; 124 | if (loadedAssetBundles[paramName].dependenceCount == 0) 125 | { 126 | loadedAssetBundles[paramName].Unload(); 127 | loadedAssetBundles.Remove(paramName); 128 | } 129 | 130 | } 131 | } 132 | 133 | private class LoadedAssetBundle 134 | { 135 | public AssetBundle assetBundle; 136 | public int dependenceCount; 137 | 138 | public LoadedAssetBundle(AssetBundle paramAssetBundle) 139 | { 140 | assetBundle = paramAssetBundle; 141 | dependenceCount = 1; 142 | } 143 | public void Unload() 144 | { 145 | assetBundle.Unload(false); 146 | } 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/FileUpdateMgr.cs: -------------------------------------------------------------------------------- 1 | //********************************************************************* 2 | // Description: 3 | // Author: hiramtan@qq.com 4 | //********************************************************************* 5 | using System; 6 | using System.Collections.Generic; 7 | using System.IO; 8 | using UnityEngine; 9 | //using System.Linq; 10 | namespace HiAssetBundle 11 | { 12 | public class FileUpdateMgr : IDisposable 13 | { 14 | public bool needUpdate { get { return updateList.Count > 0; } } 15 | public float progress { get; private set; } 16 | private string url; 17 | private Action checkFinishHandler; 18 | private Action finishHandler; 19 | private Dictionary newDic = new Dictionary(); 20 | private List updateList = new List(); 21 | private float totalCount; 22 | private byte[] fileInfoBytes; 23 | private bool disposed; 24 | public void Init(string paramUrl, Action paramCallBack) 25 | { 26 | url = paramUrl; 27 | checkFinishHandler = paramCallBack; 28 | SetNewDic(); 29 | } 30 | #region only for test, will simulate update file from streamingAsset folder to user's data folder 31 | public void Init_OnlyForTest(Action paramCallBack) 32 | { 33 | #if UNITY_EDITOR || UNITY_IPHONE 34 | string downloadUrl = "file://" + Application.streamingAssetsPath + "/" + AssetBundleUtility.fileFolderName; 35 | #else 36 | string downloadUrl = Application.streamingAssetsPath + "/" + AssetBundleUtility.fileFolderName; 37 | #endif 38 | Init(downloadUrl, paramCallBack); 39 | } 40 | #endregion 41 | 42 | private void SetNewDic() 43 | { 44 | string fileUrl = url + "/" + AssetBundleUtility.fileName; 45 | fileUrl = fileUrl.Replace(" ", string.Empty); 46 | WWWLoader.Instance.Startload(fileUrl, FinishDownloadFileInfo); 47 | } 48 | private void FinishDownloadFileInfo(WWW paramWWW) 49 | { 50 | newDic.Clear(); 51 | fileInfoBytes = paramWWW.bytes; 52 | string text = paramWWW.text; 53 | string[] lines = text.Split(new char[] { '\r', '\n' }); 54 | foreach (string paramLine in lines) 55 | { 56 | if (string.IsNullOrEmpty(paramLine)) 57 | continue; 58 | string[] keyValue = paramLine.Split('|'); 59 | newDic.Add(keyValue[0].Trim(), new UpdateFileInfo(keyValue[1].Trim(), float.Parse(keyValue[2].Trim()))); 60 | } 61 | CompareFile(); 62 | GetUpdateDic(); 63 | } 64 | private void GetUpdateDic() 65 | { 66 | float length = 0; 67 | foreach (UpdateFileInfo param in newDic.Values) 68 | { 69 | length += param.length; 70 | updateList.Add(param.path); 71 | } 72 | checkFinishHandler(length); 73 | } 74 | public void StartUpdate(Action param) 75 | { 76 | finishHandler = param; 77 | if (needUpdate) 78 | { 79 | totalCount = updateList.Count; 80 | DownloadFile(); 81 | } 82 | else 83 | Finish(); 84 | } 85 | 86 | private void CompareFile() 87 | { 88 | string fileFolder = AssetBundleUtility.GetFileFolder(); 89 | if (!Directory.Exists(fileFolder)) 90 | return; 91 | DirectoryInfo directoryInfo = new DirectoryInfo(fileFolder); 92 | FileInfo[] fileInfos = directoryInfo.GetFiles("*.*", SearchOption.AllDirectories); 93 | foreach (FileInfo paramInfo in fileInfos) 94 | { 95 | string filePath = paramInfo.FullName.Replace("\\", "/"); 96 | if (filePath == AssetBundleUtility.GetFileFolder() + "/" + AssetBundleUtility.fileName) 97 | continue; 98 | string md5 = AssetBundleUtility.GetMd5(filePath); 99 | if (newDic.ContainsKey(md5)) 100 | newDic.Remove(md5);//don't need update 101 | else 102 | File.Delete(filePath);//clean old file 103 | } 104 | } 105 | private void DownloadFile() 106 | { 107 | if (needUpdate) 108 | { 109 | string downloadUrl = url + "/" + updateList[0]; 110 | WWWLoader.Instance.Startload(downloadUrl, FinishDownloadFile); 111 | } 112 | else 113 | Finish(); 114 | } 115 | private void FinishDownloadFile(WWW paramWWW) 116 | { 117 | string filePath = AssetBundleUtility.GetFileFolder() + "/" + updateList[0]; 118 | string directory = Path.GetDirectoryName(filePath); 119 | if (!Directory.Exists(directory)) 120 | Directory.CreateDirectory(directory); 121 | File.WriteAllBytes(filePath, paramWWW.bytes); 122 | updateList.RemoveAt(0); 123 | DownloadFile(); 124 | if (updateList != null) 125 | progress = (totalCount - updateList.Count) / totalCount; 126 | } 127 | private void Finish()//when finish downloading whole files 128 | { 129 | string filePath = AssetBundleUtility.GetFileFolder() + "/" + AssetBundleUtility.fileName; 130 | string directory = Path.GetDirectoryName(filePath); 131 | if (!Directory.Exists(directory)) 132 | Directory.CreateDirectory(directory); 133 | File.WriteAllBytes(filePath, fileInfoBytes); 134 | AssetBundleMgr.Init(); 135 | finishHandler(); 136 | Dispose(); 137 | } 138 | 139 | public void Dispose() 140 | { 141 | Dispose(true); 142 | GC.SuppressFinalize(this); 143 | } 144 | ~FileUpdateMgr() 145 | { 146 | Dispose(false); 147 | } 148 | void Dispose(bool paramDisposing) 149 | { 150 | if (disposed) 151 | return; 152 | if (paramDisposing) 153 | { 154 | newDic = null; 155 | updateList = null; 156 | fileInfoBytes = null; 157 | checkFinishHandler = null; 158 | finishHandler = null; 159 | } 160 | disposed = true; 161 | } 162 | private class UpdateFileInfo 163 | { 164 | public string path; 165 | public float length; 166 | public UpdateFileInfo(string paramPath, float paramLength) 167 | { 168 | path = paramPath; 169 | length = paramLength; 170 | } 171 | } 172 | } 173 | } -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/Editor/AssetBundleBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using UnityEditor; 3 | using UnityEngine; 4 | using System.Collections.Generic; 5 | 6 | 7 | namespace HiAssetBundle 8 | { 9 | public class AssetBundleBuider 10 | { 11 | //private static BuildAssetBundleOptions options = BuildAssetBundleOptions.None;//none is defalt is lamz 12 | private static BuildAssetBundleOptions options = BuildAssetBundleOptions.ChunkBasedCompression;//lz4 is high performance when load ab 13 | 14 | [MenuItem("AssetBundles/Build", false, 0)] 15 | public static void BuildWindows() 16 | { 17 | Build(EditorUserBuildSettings.activeBuildTarget); 18 | } 19 | [MenuItem("AssetBundles/Clean User's Data", false, 10)] 20 | public static void Clean() 21 | { 22 | string path = AssetBundleUtility.GetFileFolder(); 23 | if (Directory.Exists(path)) 24 | Directory.Delete(path, true); 25 | Debug.Log("clean finish"); 26 | } 27 | private static void Build(BuildTarget param) 28 | { 29 | string fileFolder = Application.streamingAssetsPath + "/" + AssetBundleUtility.fileFolderName; 30 | if (Directory.Exists(fileFolder)) 31 | Directory.Delete(fileFolder, true); 32 | string assetBundleFolder = fileFolder + "/" + AssetBundleUtility.GetPlatformName(param); 33 | if (!Directory.Exists(assetBundleFolder)) 34 | Directory.CreateDirectory(assetBundleFolder); 35 | BuildPipeline.BuildAssetBundles(assetBundleFolder, options, param); 36 | GenerateFileInfo(fileFolder); 37 | Debug.Log("Finish build assetbundle"); 38 | } 39 | private static void GenerateFileInfo(string param) 40 | { 41 | string fileFolder = param; 42 | DirectoryInfo directoryInfo = new DirectoryInfo(fileFolder); 43 | string fileInfoPath = fileFolder + "/" + AssetBundleUtility.fileName; 44 | FileInfo[] fileInfos = directoryInfo.GetFiles("*.*", SearchOption.AllDirectories); 45 | FileStream stream = new FileStream(fileInfoPath, FileMode.CreateNew); 46 | StreamWriter writer = new StreamWriter(stream); 47 | float total, processed = 0; 48 | total = fileInfos.Length; 49 | foreach (FileInfo paramFileInfo in fileInfos) 50 | { 51 | processed++; 52 | EditorUtility.DisplayProgressBar(AssetBundleUtility.fileName, "Progress", processed / total); 53 | string fileInfo = paramFileInfo.FullName; 54 | if (fileInfo.EndsWith(".meta")) 55 | continue; 56 | long length = paramFileInfo.Length; 57 | string md5 = AssetBundleUtility.GetMd5(fileInfo); 58 | fileInfo = fileInfo.Replace("\\", "/"); 59 | fileInfo = fileInfo.Replace(fileFolder + "/", string.Empty); 60 | writer.WriteLine(md5 + "|" + fileInfo + "|" + length); 61 | } 62 | EditorUtility.ClearProgressBar(); 63 | writer.Close(); 64 | stream.Close(); 65 | } 66 | 67 | /// 68 | /// use mouse select folder in unity editor, then click"AssetBundles/Rename sources a new name"button to rename sources 69 | /// note: only can select one folder at one time 70 | /// 71 | [MenuItem("AssetBundles/Rename sources a new name", false, 11)] 72 | private static void RenameSources() 73 | { 74 | string tempSplit = "__";//use this sign to split directory 75 | 76 | string tempSelectedFolder = ""; 77 | foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) 78 | { 79 | tempSelectedFolder = AssetDatabase.GetAssetPath(obj); 80 | if (!string.IsNullOrEmpty(tempSelectedFolder) && File.Exists(tempSelectedFolder)) 81 | { 82 | tempSelectedFolder = Path.GetDirectoryName(tempSelectedFolder); 83 | break; 84 | } 85 | } 86 | if (string.IsNullOrEmpty(tempSelectedFolder)) 87 | return; 88 | tempSelectedFolder = tempSelectedFolder.Replace("Assets", Application.dataPath); 89 | DirectoryInfo tempDInfo = new DirectoryInfo(tempSelectedFolder); 90 | FileInfo[] tempFInfo = tempDInfo.GetFiles("*.*", SearchOption.AllDirectories); 91 | float tempProcessed = 0; 92 | float tempTotal = tempFInfo.Length; 93 | foreach (var param in tempFInfo) 94 | { 95 | tempProcessed++; 96 | EditorUtility.DisplayProgressBar("Progress", param.Name, tempProcessed / tempTotal); 97 | string tempPath = param.ToString(); 98 | if (tempPath.EndsWith(".meta")) 99 | continue; 100 | if (tempPath.Contains(tempSplit))//already name it, donnt need to rename it again 101 | continue; 102 | tempPath = tempPath.Replace(@"\", "/"); 103 | tempPath = tempPath.Substring(tempPath.IndexOf("Assets")); 104 | int tempIndex = tempPath.IndexOf("/") + 1; 105 | string tempName = tempPath.Substring(tempIndex); 106 | tempIndex = tempName.LastIndexOf("."); 107 | tempName = tempName.Substring(0, tempIndex); 108 | tempName = tempName.Replace("/", tempSplit); 109 | string tempError = AssetDatabase.RenameAsset(tempPath, tempName); 110 | if (!string.IsNullOrEmpty(tempError)) 111 | Debug.Log(tempError); 112 | } 113 | EditorUtility.ClearProgressBar(); 114 | AssetDatabase.Refresh(); 115 | } 116 | 117 | /// 118 | /// use mouse select folder 119 | /// 120 | [MenuItem("AssetBundles/Set file an assetbundle name", false, 12)] 121 | private static void SetFileAnAssetBundleName() 122 | { 123 | string tempSelectedFolder = ""; 124 | foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) 125 | { 126 | tempSelectedFolder = AssetDatabase.GetAssetPath(obj); 127 | if (!string.IsNullOrEmpty(tempSelectedFolder) && File.Exists(tempSelectedFolder)) 128 | { 129 | tempSelectedFolder = Path.GetDirectoryName(tempSelectedFolder); 130 | break; 131 | } 132 | } 133 | if (string.IsNullOrEmpty(tempSelectedFolder)) 134 | return; 135 | 136 | //string tempPrefabPath = Application.dataPath + "/Example"; 137 | DirectoryInfo tempDInfo = new DirectoryInfo(tempSelectedFolder); 138 | FileInfo[] tempFInfo = tempDInfo.GetFiles("*.*", SearchOption.AllDirectories); 139 | //IList tempList = new List(); 140 | //for (int i = 0; i < tempFInfo.Length; i++) 141 | //{ 142 | // string tempFileName = tempFInfo[i].Name.ToLower(); 143 | // if (tempFileName.EndsWith(".prefab") || tempFileName.EndsWith(".mat")) 144 | // tempList.Add(tempFileName); 145 | //} 146 | foreach (var VARIABLE in tempFInfo) 147 | { 148 | string tempPath = VARIABLE.ToString(); 149 | tempPath = tempPath.Replace(@"\", " / "); 150 | tempPath = tempPath.Replace(" ", ""); 151 | tempPath = tempPath.Substring(tempPath.IndexOf("Assets")); 152 | AssetImporter tempAImporter = AssetImporter.GetAtPath(tempPath); 153 | int tempIndex = tempPath.IndexOf("/") + 1; 154 | tempPath = tempPath.Substring(tempIndex); 155 | tempIndex = tempPath.LastIndexOf("/"); 156 | tempPath = tempPath.Substring(0, tempIndex); 157 | tempPath = tempPath.Replace("/", ""); 158 | tempPath = tempPath.ToLower(); 159 | if (tempAImporter != null) 160 | tempAImporter.assetBundleName = tempPath; 161 | else 162 | Debug.LogError("this prefab cann't set name: +" + tempPath); 163 | } 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /unity/Assets/Script/Core/AssetBundle/AssetBundleUtility.cs: -------------------------------------------------------------------------------- 1 | //********************************************************************* 2 | // Description: 3 | // Author: hiramtan@qq.com 4 | //********************************************************************* 5 | using UnityEngine; 6 | using System.IO; 7 | using System.Text; 8 | using System; 9 | #if UNITY_EDITOR 10 | using UnityEditor; 11 | #endif 12 | 13 | namespace HiAssetBundle 14 | { 15 | public class AssetBundleUtility 16 | { 17 | public static readonly string fileFolderName = "File"; 18 | public static readonly string fileName = "file.txt"; 19 | public static string GetFileFolder() 20 | { 21 | return Application.persistentDataPath + "/" + fileFolderName; 22 | } 23 | public static string GetAssetBundleFolder() 24 | { 25 | #if UNITY_EDITOR 26 | string directory = GetFileFolder() + "/" + 27 | GetPlatformName(EditorUserBuildSettings.activeBuildTarget); 28 | #else 29 | string directory = GetFileFolder() + "/" + 30 | GetPlatformName(Application.platform); 31 | #endif 32 | return directory; 33 | } 34 | public static string GetManifestPath() 35 | { 36 | #if UNITY_EDITOR 37 | string directory = GetAssetBundleFolder() + "/" + 38 | GetPlatformName(EditorUserBuildSettings.activeBuildTarget); 39 | #else 40 | string directory = GetAssetBundleFolder() + "/" + 41 | GetPlatformName(Application.platform); 42 | #endif 43 | return directory; 44 | } 45 | public static string GetMd5(string file) 46 | { 47 | try 48 | { 49 | FileStream fs = new FileStream(file, FileMode.Open); 50 | System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); 51 | byte[] retVal = md5.ComputeHash(fs); 52 | fs.Close(); 53 | System.Text.StringBuilder sb = new StringBuilder(); 54 | for (int i = 0; i < retVal.Length; i++) 55 | { 56 | sb.Append(retVal[i].ToString("x2")); 57 | } 58 | return sb.ToString(); 59 | } 60 | catch (Exception ex) 61 | { 62 | throw new Exception("md5file() fail, error:" + ex.Message); 63 | } 64 | } 65 | private static UInt32[] Crc32Table = { 66 | 0x00000000,0x77073096,0xEE0E612C,0x990951BA, 67 | 0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3, 68 | 0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988, 69 | 0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91, 70 | 0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE, 71 | 0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7, 72 | 0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC, 73 | 0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5, 74 | 0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172, 75 | 0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B, 76 | 0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940, 77 | 0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59, 78 | 0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116, 79 | 0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, 80 | 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924, 81 | 0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D, 82 | 0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A, 83 | 0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433, 84 | 0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818, 85 | 0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01, 86 | 0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E, 87 | 0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457, 88 | 0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C, 89 | 0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65, 90 | 0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2, 91 | 0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB, 92 | 0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0, 93 | 0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, 94 | 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086, 95 | 0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F, 96 | 0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4, 97 | 0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD, 98 | 0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A, 99 | 0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683, 100 | 0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8, 101 | 0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1, 102 | 0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE, 103 | 0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7, 104 | 0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC, 105 | 0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5, 106 | 0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252, 107 | 0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, 108 | 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60, 109 | 0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79, 110 | 0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236, 111 | 0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F, 112 | 0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04, 113 | 0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D, 114 | 0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A, 115 | 0x9C0906A9,0xEB0E363F,0x72076785,0x05005713, 116 | 0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38, 117 | 0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21, 118 | 0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E, 119 | 0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777, 120 | 0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C, 121 | 0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, 122 | 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2, 123 | 0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB, 124 | 0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0, 125 | 0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9, 126 | 0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6, 127 | 0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF, 128 | 0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94, 129 | 0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D}; 130 | public static string GetCRC32(string paramPath) 131 | { 132 | UInt32 crc = 0xFFFFFFFF; 133 | var bin = File.ReadAllBytes(paramPath); 134 | foreach (byte b in bin) 135 | { 136 | crc = ((crc >> 8) & 0x00FFFFFF) ^ Crc32Table[(crc ^ b) & 0xFF]; 137 | } 138 | crc = crc ^ 0xFFFFFFFF; 139 | return crc.ToString("X"); 140 | } 141 | 142 | private static string GetPlatformName(RuntimePlatform platform) 143 | { 144 | switch (platform) 145 | { 146 | case RuntimePlatform.Android: 147 | return "Android"; 148 | case RuntimePlatform.IPhonePlayer: 149 | return "iOS"; 150 | #if UNITY_5_3_1 151 | case RuntimePlatform.tvOS: 152 | return "tvOS"; 153 | #endif 154 | case RuntimePlatform.WebGLPlayer: 155 | return "WebGL"; 156 | case RuntimePlatform.OSXWebPlayer: 157 | case RuntimePlatform.WindowsWebPlayer: 158 | return "WebPlayer"; 159 | case RuntimePlatform.WindowsPlayer: 160 | return "Windows"; 161 | case RuntimePlatform.OSXPlayer: 162 | return "OSX"; 163 | default: 164 | return null; 165 | } 166 | } 167 | 168 | #if UNITY_EDITOR 169 | public static string GetPlatformName(BuildTarget target) 170 | { 171 | switch (target) 172 | { 173 | case BuildTarget.Android: 174 | return "Android"; 175 | #if UNITY_TVOS 176 | case BuildTarget.tvOS: 177 | return "tvOS"; 178 | #endif 179 | case BuildTarget.iOS: 180 | return "iOS"; 181 | case BuildTarget.WebGL: 182 | return "WebGL"; 183 | case BuildTarget.WebPlayer: 184 | return "WebPlayer"; 185 | case BuildTarget.StandaloneWindows: 186 | case BuildTarget.StandaloneWindows64: 187 | return "Windows"; 188 | case BuildTarget.StandaloneOSXIntel: 189 | case BuildTarget.StandaloneOSXIntel64: 190 | case BuildTarget.StandaloneOSXUniversal: 191 | return "OSX"; 192 | default: 193 | return null; 194 | } 195 | } 196 | #endif 197 | } 198 | } 199 | --------------------------------------------------------------------------------