2015-02-08 17:24:04 u014678046 阅读数 1633
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

对于Unity3d的资源管理已经研究了很久,大概是从大学毕业到现在,依然在不断的探索着,这期间不断的在网上查看各位大神们的讲解,然后自己就研究,也做部分实验,发现其实要很好地管理起来是很容易的,资源更新,加载,卸载对于一款游戏来说是十分重要的,首先我从资源更新说起。

一、资源更新现在有很多的办法,Unity3d提供了很多种资源管理方式。1、你可以将资源存放在工程目录的Resource文件夹下面,这个文件夹下面的资源会随着你导出平台安装包的时候加密到你的安装包里面,unity程序在运行的时候会根据自己的资源加载思路将场景里面用到的资源进行加载,但是这部分资源是不能够及时更新的,也就是说,资源跟新不能考虑这个文件夹;2、unity工程下面还有一个特殊的文件夹,就是StreamingAssets文件夹,这个文件夹会在你导出的时候原封不动的考到安装包里面,在释放到平台上面,注意一点,他是原封不动的,这就需要你采用自己的加密方式,要不会很容易被破解的,这部分资源在各个平台上是可以访问到,安卓手机上面用WWW类进行读取,PC,以及iPhone可以用File类进行读取,很方便。上述两个文件夹是unity提供给我们的,很方便,哈哈。
我自己在研究了那么久之后,决定将大部分用到的,可能需要经常更新的资源存放到了StreamingAssets目录下面,有用到的ngui的图集,以及预设等等,由于iPhone不支持代码更新,我们就在脚本中运用了lua代码,我们采用的是ulua,这都是跟着群里面的大神学习的,首先游戏安装到设备上头一回运行的时候,会将StreamingAssets下面的资源进行复制,释放到平台上面我们自己指定的目录,需要获得读写权限,这个路径Application.streamingAssetsPath就是平台上面的StreamingAssets所在的位置,然后在安卓手机上面访问内置sd卡或sd卡1的路径为/mnt/sdcard,在4.1以后也可用路径/storage/sdcard0这个路径,最后在这个历经下面建立文件夹,存放自己的资源。在iPhone以及PC上面完全可以使用Application.persistentDataPath这个目录进行资源的存放。资源存放好了就可以准备更新了,www可以访问你自己的资源服务器,游戏资源存放得当之后便可以调用new WWW(地址);来进行下载,我们的做法是资源释放到了本地,然后会从服务器上面下载最新的资源配置文件,lua太伟大了,既可以写程序也可以作为配置文件,哈哈,我就将资源的名称以及他们的md5值存放在lua的table里面,然后就是表的遍历了,方法很多,ulua在这方面已经完全可以胜任,支持安卓PC以及iPhone,wp推荐用nlua,nlua我不会,哈哈,怎样打assetbundle类型的资源包网上教程很多,也很详细,如果资源包过大,也可以考虑一下采用压缩,有7z,网上有宣雨松的例子,很好。遍历配置表格,进行md5比对,不同的就进行下载,最终进入游戏。建议是资源尽量分的细一些,这样既方便局部资源的整体替换,同时也有利于团队分工开发,后期的更新维护也会很简单,你可以参考一下别人的安装包,解压看看里面的资源是怎么布置的,看看就好呀,哈哈。共同学习。
二、下面就是资源的加载了,建议大家对Resource类进行适当的利用然后写出一个自己能够方便使用的资源加载类,首先可以从Resource目录下面方便的加载,然后还要很方便的从assetbundle里面进行加载,assetbundle里面的资源你想要用的时候要提前加载,建议做在loading界面里面,这样用户体验会好一些,因为此时用户的耐心是最大的,你一卡一卡的,老板都会揍你,哈哈,这个加载类可以加载assetbundle里面的东西,并将加载的assetbundle交给全局的加载对象管理器,以便进行及时的释放,关于assetbundle的完全释放,网上讲的很多,也很好,我这里面总结一下整体的过程,仅供参考:
1.首先记录下已经加载的assetbundle,以便你好释放;
2.将预设或者图集,图片从里面加载出来,记录;
3.将在第2步里面加载的东西放到场景的某个对象上面,或者直接实例化预设,将这个放到场景里面的这个对象记录下来,因为它上面有对asser的引用;
4.在一个assetbundlle里面所有的用到的资源都加在出来之后,执行语句Resources.UnloadUnusedAssets();会将不用了的asset占用的内存释放出来;
5.场景中通过某一个assetbundle创建的对象或者依附的对象没什么用处的时候,将对象进行Destroy(对象);这个方法,这样对象会从场景里面消失,同时它所引用的资源就没有存在的意义了;
6.将销毁的对象所用的assetbundle执行assetbundle.Unload(false);,这样就会将已经记录的资源包所占用的内存镜像会完全卸载;
7.Resources.UnloadUnusedAssets();卸载没有用到的资源;
8.将记录的加载过的预设,等资源设置为null;
9.Resources.UnloadUnusedAssets();释放资源,
10.调用系统的垃圾回收站清理函数GC.Collect();
通过上面十个步骤,就可以将引用的assetbundle进行彻底的释放,由于在代码里面我与用到了lua脚本,就可能会存在lua的引用,这时需要在第8个步骤里面调用一下lua自身的垃圾回收函数collectgarbage();然后再进行第9步,实验证明是可以的。
我在实际的过程中就是采用的如此的资源更新,加载,以及释放的过程,很方便,没有提到的就是工程里面要有一个对象管理器,就是对象池,需要你对对象进行比较明确的管理,时刻明白场景里面哪些是有用的,哪些是可以释放卸载掉的,这样,unity3d的游戏在平台上才不会内存一直飙高,可能引起的游戏闪退等现象,卡顿也会避免。
最后,大家加油呀!快过年了,程序员还没放假,哈哈
下面是我自己的部分代码,很简单的,只供参考,嘿嘿

--关闭面板(Lua脚本),将场景里面的已将创建的面板进行销毁--GameObjectMgr是我自己写的一个很简单的管理器
function CloseWindow(args)
    if(args==nil)then
        print('ERROR    变量未正确赋值');
        return;
    end

    local   _iswindestory       =args['_iswindestory']
    local   _winname            =args['_winname']
    local   _isassetdestory =args['_isassetdestory']
    local   _assetname          =args['_assetname']
    local   _ispbdestory        =args['_ispbdestory']
    local   _prefabname         =args['_prefabname']

    if(GameObjectMgr.IsObjCreated(_winname)==false)then
        print("指定窗口不存在,不需要关闭 :",_winname);
        return;
    end

    args =nil;

    if(_ispbdestory)then
        GameObjectMgr.AdddestoryPerfabList (_prefabname);
    end
    if(_iswindestory)then
        print('销毁窗口');
        GameObjectMgr.AdddestoryObjNameList (_winname);
    else
        print('窗口隐藏');
        GameObjectMgr.SetObjActivePority(_winname,false);
    end
    if(_isassetdestory)then
        GameObjectMgr.AdddestoryABList (_assetname);
    end
    collectgarbage();
    --下面将会进行对象销毁,内存释放内存释放
    GameObjectMgr.FreeMemory ();

end

改日把我的GameObjectMgr也加进来,供大家参考,周末愉快,下周末我也就放假啦,哈哈哈,开心的等待着

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GameObjectMgr{

    public static       Dictionary<string,GameObject>           loadedPerfabList        =null;      //存放已经加载的预设资源
    public static       Dictionary<string,AssetBundle>          loadedAssetList         =null;      //存放AB包
    public static       Dictionary<string,GameObject>           createdObjList          =null;      //存放创建的对象

    public static       string[]                                destoryPerfabList       =null;      //销毁的预设
    public static       string[]                                destoryAssetList            =null;      //销毁的AB包,unload(false);
    public static       string[]                                destoryObjNameList      =null;      //销毁的对象;
    //设置是否显示
    public static void SetObjActivePority(string _name,bool _active){
        if (createdObjList == null) {
        } else {
            foreach(string key in createdObjList.Keys){
                if(key==_name){
                    if(createdObjList[key]!=null){
                        createdObjList[key].SetActive(_active);
                    }else{
                        createdObjList.Remove(_name);
                    }
                }               
            }   
        }

    }
    //获得一个已经创建的对象
    public static GameObject GetGameObjectByName(string _name){    
        if (createdObjList == null) {
            return null;
        } else {
            foreach(string key in createdObjList.Keys){
                if(key==_name){
                    if(createdObjList[key]!=null){
                        return createdObjList[key];
                    }else{
                        createdObjList.Remove(_name);
                        return null;
                    }
                }               
            }   
        }
        return null;
    }
    //获得一个已经加载的预设
    public static GameObject GetPrefabByName(string _name){    
        if (loadedPerfabList == null) {
            return null;
        } else {
            foreach(string key in loadedPerfabList.Keys){
                if(key==_name){
                    if(loadedPerfabList[key]!=null){
                        return loadedPerfabList[key];
                    }else{
                        loadedPerfabList.Remove(_name);
                        return null;
                    }
                }               
            }   
        }
        return null;
    }

    //查看预设是否加载
    public static bool IsPerfabLoaded(string _name){
        if (loadedPerfabList == null) {
            return false;
        } else {
            foreach(string key in loadedPerfabList.Keys){
                if(key==_name){
                    if(loadedPerfabList[key]!=null)
                        return true;
                    else{
                        loadedPerfabList.Remove(_name);
                        return false;
                    }
                }               
            }   
        }
        return false;
    }
    //对象是否已经被创建
    public static bool IsObjCreated(string _name){
        if (createdObjList == null) {
            return false;
        } else {
            foreach(string key in createdObjList.Keys){
                if(key==_name){
                    if(createdObjList[key]!=null){
                        return true;
                    }else{
                        createdObjList.Remove(_name);
                        return false;
                    }
                }               
            }   
        }
        return false;
    }

    //添加已经创建
    public static void AddCreatedObjList(string _name, GameObject _obj){
        if (createdObjList == null) {
            createdObjList = new Dictionary<string, GameObject>();  
        }
        if(createdObjList.ContainsKey(_name)){
            return ;
        }
        createdObjList.Add (_name,_obj);
    }
    //添加已经加载的assetbundle
    public static void AddloadedAssetList(string _name, AssetBundle _obj){
        if (loadedAssetList == null) {
            loadedAssetList = new Dictionary<string, AssetBundle>();    
        }
        if(loadedAssetList.ContainsKey(_name)){
            return ;
        }
        loadedAssetList.Add (_name,_obj);
    }

    //添加已经加载的预设
    public static void AddloadedPerfabList(string _name, GameObject _obj){
        if (loadedPerfabList == null) {
            loadedPerfabList = new Dictionary<string, GameObject>();    
        }
        if(loadedPerfabList.ContainsKey(_name)){
            return ;
        }
        loadedPerfabList.Add (_name,_obj);
    }

    //添加预设名字
    public static void AdddestoryPerfabList(string _name){
        if (destoryPerfabList == null) {
            destoryPerfabList = new string[1];
            destoryPerfabList[0] = _name;
            return;
        } else {
            int j = destoryPerfabList.Length;
            destoryPerfabList[j] = _name;
            return;
        }
    }

    //添加对象名字
    public static void AdddestoryObjNameList(string _name){
        if (destoryObjNameList == null) {
            destoryObjNameList = new string[1];
            destoryObjNameList[0] = _name;
            return;
        } else {
            int i=destoryObjNameList.Length;
            destoryObjNameList[i] = _name;
            return;
        }
    }
    //添加assetbundle名字
    public static void AdddestoryABList(string _name){
        if (destoryAssetList == null) {
            destoryAssetList = new string[1];
            destoryAssetList[0] =_name;
            return;
        } else {
            int j = destoryAssetList.Length;
            destoryAssetList[j] = _name;
            return;
        }
    }
    //清理内存
    public static void FreeMemory(){
        if (destoryObjNameList == null&&destoryPerfabList.Length== null&&destoryAssetList== null) {
            Debug.Log("不需要释放资源");   
            return;
        }
        int i = 0;
        if (destoryObjNameList != null) {
            i = destoryObjNameList.Length;
            for(int j = i-1;j>=0;j--){
                if(destoryObjNameList[j]!=null)
                if(createdObjList.ContainsKey(destoryObjNameList[j])){
                    GameObject obj=createdObjList[destoryObjNameList[j]];
                    createdObjList.Remove(destoryObjNameList[j]);
                    GameObject.Destroy(obj);
                }
                destoryObjNameList[j]=null;
            }   
        }

        destoryObjNameList = null;
        if (destoryPerfabList != null) {
            i = destoryPerfabList.Length;
            for(int j = i-1;j>=0;j--){
                if(destoryPerfabList[j]!=null)
                if(loadedPerfabList.ContainsKey(destoryPerfabList[j])){
                    loadedPerfabList[destoryPerfabList[j]]=null;
                    loadedPerfabList.Remove(destoryPerfabList[j]);
                }
                destoryPerfabList[j]=null;
            }   
        }

        destoryPerfabList = null;

        if (destoryAssetList == null || destoryAssetList.Length == 0) {
        } else {
            i = destoryAssetList.Length;
            for(int j =i-1;j>=0;j--){
                if(destoryAssetList[j]!=null)
                    if(loadedAssetList.ContainsKey(destoryAssetList[j]))
                        AssetBundle asset = loadedAssetList[destoryAssetList[j]];
                        loadedAssetList.Remove(destoryAssetList[j]);
                        asset.Unload(false);
                    }
                destoryAssetList[j]=null;
            }
        }

        destoryAssetList = null;
        Resources.UnloadUnusedAssets ();
        System.GC.Collect ();
    }
}
2018-05-13 17:40:40 qq_36512517 阅读数 478
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

/*
* <资源打包介绍>
* 首先会根据已经建好的文件进行遍历,找到所有预制物并设置AssetBundleName,因为是遍历Resources下面的文件夹,
* 所以可以将每个文件夹里的所有预制物打成一个包,然后打包到StreamingAssets 下面,并会生成一个配置文件,这个
* 配置文件是以Resources下的文件夹命名的,一个文件夹一个配置文件,方便后面的更新资源,这个配置文件是根据打包
* 好的包文件生成的,每行都记录了单个包的路径+;+.manifest文件里的crc码,当每次打包预制物有改变时,crc码会重新
* 生成,更新资源时会通过配置文件里每个包路径后面的crc码来判断这个包是否需要更新。
*
*
* 所有需要打包的预制物需要放入文件夹 AssetBundleResources/Resources 下进行打包.
* 打包出来的文件会在 Assets/StreamingAssets(没有该文件夹会自动创建) 文件夹下生成.
*
* 路径供阅读下面代码参考
* 完整的需要打包路径:Assets\AssetBundleResources\Resources\Prefad\UI\XXX.prefab
* 完整的打包好的路径(安卓):Assets\StreamingAssets\Android\resources\prefad\ui\XXX.unity3d
* 完整的配置文件路径:Assets\StreamingAssets\Android\configuration\prefad\ui.txt
*
*
* 因为unity5.X不需要我们来管理引用, 所以下面的代码大部分都是对路径和文件夹的处理,打包的代码也就两行
* 1:设置AssetBundleName
*:2:根据平台设置进行打包
*
* 该段代码打包流程
* 清除已设置的AssetBundleName -→ 找到要打包的资源并设置 AssetBundleName -→ 进行打包 -→ 创建文本并写入配置信息
*
* 调用该函数,unity会自动根据资源的标签进行打包,而且是增量打包,
* a.对于资源没有变更的bundle包,不会触发重新打包;
* b.资源没变,即使生成目录下的bundle包被删除了,unity也不会重新打包;
* c.生成目录下的bundle包对应的manifase被删了,会重新打包;
* d.可以使用BuildAssetBundleOptions.ForceRebuildAssetBundle参数触发强制重新打包。
*
*
*/
public class Builder : Editor
{

[MenuItem("打包/热更新打包")]
public static void BuildAssetBundleAll()
{
#if UNITY_ANDROID && UNITY_EDITOR
BuildResource(BuildTarget.Android);
#endif
#if UNITY_IOS && UNITY_EDITOR
BuildResource(BuildTarget.iOS);
#endif
}
/// <summary>
/// 资源打包
/// </summary>
/// <param name="target">打包平台</param>
static void BuildResource(BuildTarget target)
{
//清除所有之前设置过的AssetBundleName
ClearAssetBundlesName();
//代码中给资源设置AssetBundleName
SetAssetBundelsName(AssetPath.OriginalPath);
//因为要根据平台打包,为了方便分类,所以在Assets\StreamingAssets目录下创建一个
//以平台名字命名的文件夹来放置各平台打出来的包和其他相关的文件,以方便管理
//例如安卓平台: 处理路径为Assets\StreamingAssets\Android
string outputPath = Path.Combine(AssetPath.StreamingAssetsPath, target.ToString());
//查找Assets\StreamingAssets路径下有没有当前平台名字的文件夹,没有的话就创建
if (!Directory.Exists(outputPath))
{
Directory.CreateDirectory(outputPath);
}
//刷新
AssetDatabase.Refresh();
//根据平台设置进行打包
BuildPipeline.BuildAssetBundles(outputPath, 0, target);
AssetDatabase.Refresh();
//生成配置文档(配置文档以游戏文件夹进行分类,一个游戏文件夹一个配置文档,方便管理)
ConfigurationFiles(target);
//刷新
AssetDatabase.Refresh();
Debug.Log("打包成功!");
}
/// <summary>
/// 清除之前设置过的AssetBundleName
/// 因为只要设置过AssetBundleName就会打包,所以这里一定要清理干净,防止重复打包
/// </summary>
static void ClearAssetBundlesName()
{
string[] strArr = AssetDatabase.GetAllAssetBundleNames();
for (int i = 0; i < strArr.Length; i++)
{
AssetDatabase.RemoveAssetBundleName(strArr[i], true);
}
AssetDatabase.RemoveUnusedAssetBundleNames();
}
/// <summary>
/// 在代码中给资源设置AssetBundleName
/// </summary>
static void SetAssetBundelsName(string folderName)
{
//首先遍历需要打包的文件夹,找到所有需要打包的文件
//AssetBundleResources/Resources/Prefad/UI 因为我的要打包的文件
//都是放在Prefad下的文件夹里面也就是UI文件里所以我需要遍历到UI文件夹里面
DirectoryInfo folder = new DirectoryInfo(folderName);
FileSystemInfo[] files = folder.GetFileSystemInfos();
for (int i = 0; i < files.Length; i++)
{
if (files[i] is DirectoryInfo)
{
SetAssetBundelsName(files[i].FullName);
}
else
{
//过滤.meta文件,并给遍历到的资源设置AssetBundleName,以路径的形式命名
//这里是一个资源一个包,也可以把多个资源打一个包中
//最好是对资源进行分类,将一些有共有资源的预制物打进一个包中
if (!files[i].Name.EndsWith(AssetPath.metaSuffix))
{
//处理前的路径C:\Users\Administrator\Desktop\DynamicLoadResource\Assets\AssetBundleResources\Resources\Prefad\UI\XXX.prefab
//处理后的路径Resources/Prefad/UI/XXX.unity3d
//这个处理后的路径会拿来设置AssetBundleName
string str1 = files[i].FullName.Replace(@"\", "/");
string path = "Assets" + str1.Substring(Application.dataPath.Length);
AssetImporter ass = AssetImporter.GetAtPath(path);
string str2 = str1.Substring(Application.dataPath.Length + 1);
str2 = str2.Substring(str2.IndexOf("/") + 1);
string assetName = str2.Replace(Path.GetExtension(str2), ".unity3d");
//这里设置AssetBundleName,AssetBundleName相同的文件会打到一个包中
ass.assetBundleName = assetName;
}
}
}
}
/// <summary>
/// 生成配置文件
/// </summary>
static void ConfigurationFiles(BuildTarget target)
{
//所有配置文件的配置文件
List<string> MapConfig = new List<string>();
//查找Assets\StreamingAssets\Android 下是否有 configuration(该文件用于放置生成的配置文件)文件夹
//有的话就删掉该文件夹(把文件夹下已存在的配置文件一起删除),然后重新创建该文件夹
string str = AssetPath.StreamingAssetsPath + "/" + target.ToString() + "/" + AssetPath.ConfigurationFilesName;
if (Directory.Exists(str))
{
Directory.Delete(str, true);
}
Directory.CreateDirectory(str);
//处理包路径
string resourcesStr = AssetPath.OriginalPath.Substring(AssetPath.OriginalPath.LastIndexOf("/") + 1);
string packetPath = Application.dataPath + "/" + AssetPath.StreamingAssets + "/" + target.ToString() + "/" + resourcesStr.ToLower();
//遍历 Assets\StreamingAssets\Android\resources 下的文件夹
//因为打出来的包并没有直接放在resources下,都是放在该文件夹里面的各个文件夹下
//所以需要再遍历resources下的各个文件夹
DirectoryInfo folder = new DirectoryInfo(packetPath);
FileSystemInfo[] files = folder.GetFileSystemInfos();
for (int i = 0; i < files.Length; i++)
{
if (files[i] is DirectoryInfo)
{
string config = str + "/" + files[i].Name;
if (Directory.Exists(config))
{
Directory.Delete(config, true);
}
Directory.CreateDirectory(config);
DirectoryInfo folder1 = new DirectoryInfo(files[i].FullName);
FileSystemInfo[] files1 = folder1.GetFileSystemInfos();
for (int n = 0; n < files1.Length; n++)
{
if (files1[n] is DirectoryInfo)
{
//配表文件路径
string configurationPath = config + "/" + files1[n].Name.Replace(AssetPath.metaSuffix, "") + ".txt";
//添加配表相对路径到总配表中
MapConfig.Add(configurationPath.Remove(0, AssetPath.StreamingAssetsPath.Length + 1));
SetCon(files1[n].FullName.Replace(AssetPath.metaSuffix, ""), configurationPath);
}
}
}
}
//最后生成所有配置文件的配置文件
string MapConfigPath = AssetPath.StreamingAssetsPath + "/" + target.ToString() + "/" + IP.ResoucelsTablePath;
string mapConfigStr = "";
for (int i = 0; i < MapConfig.Count; i++)
{
mapConfigStr += MapConfig[i];
mapConfigStr += System.Environment.NewLine;
}
File.WriteAllText(MapConfigPath, mapConfigStr);
}
/// <summary>
/// 向配置文件中写入ab包路径与标识
/// </summary>
/// <param name="path"></param>
/// <param name="textPath"></param>
static void SetCon(string path, string textPath)
{
string content = "";
string[] assetPath = Directory.GetFiles(path, "*.manifest", SearchOption.AllDirectories);
for (int i = 0; i < assetPath.Length; i++)
{
content += assetPath[i].Replace(Application.dataPath.Replace("/", "\\") + "\\", "").Replace(".manifest", "").Replace(AssetPath.StreamingAssets + "\\", "");
content += ";";
content += File.ReadAllLines(assetPath[i])[1].Replace("CRC:", "").Trim();
content += System.Environment.NewLine;
}
File.WriteAllText(textPath, content.Replace('\\','/'));
}


}


public class AssetPath
{
/// <summary>
/// 需要打包的文件夹路径
/// </summary>
public static string OriginalPath = Application.dataPath + "/AssetBundleResources/Resources";
/// <summary>
/// 打包出来的文件夹路径
/// </summary>
public const string StreamingAssetsPath = @"Assets/StreamingAssets";
/// <summary>
/// 配置文件夹
/// </summary>
public const string ConfigurationFilesName = "configuration";
/// <summary>
/// 资源文件夹
/// </summary>
public const string ResourcesFilesName = "resources";
/// <summary>
/// 资源文件后缀名
/// </summary>
public const string unity3dSuffix = ".unity3d";
/// <summary>
/// .meta后缀名
/// </summary>
public const string metaSuffix = ".meta";
/// <summary>
/// 打包目录
/// </summary>
public const string StreamingAssets = "StreamingAssets";
/// <summary>
/// Android
/// </summary>
public const string _Android = "Android";
/// <summary>
/// IPhonePlayer
/// </summary>
public const string _IPhonePlayer = "IPhonePlayer";
/// <summary>
/// 移动端本地压缩包路径
/// </summary>
public static string streamingPath = Application.streamingAssetsPath + "/" + Application.platform;
/// <summary>
/// 移动端资产放置路径
/// </summary>
public static string persistentPath = Application.persistentDataPath + "/" + Application.platform;
/// <summary>
/// 预留物配表相对路径
/// </summary>
public const string scheduledFileName = "/"+ConfigurationFilesName+"/prefad/scheduled.txt";
/// <summary>
/// "jar:file"
/// </summary>
public const string jarHead = "jar:file";
/// <summary>
/// "http"
/// </summary>
public const string httpHead = "http";

/// <summary>
/// 配置物
/// </summary>
public const string source = "source";

}



2014-01-17 10:59:56 s10141303 阅读数 5589
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

1.首先我们把这段代码拷贝下来,放进工程,不要托给任何物体,就放在那不要理它。

using UnityEngine;
using UnityEditor;
public class ExportAssetBundles {
    [MenuItem("Export/Build AssetBundle 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;
        }
    }
    [MenuItem("Export/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);
        }
    }
}
我们仔细看一下,其实打包的.unity3d格式的文件也类似assenbundle,只不过是换了个不同的后缀名而已。

当我们创建完,保存好后我,我们会发现菜单的导航栏多了这2项

 

2.我们在选中我们需要打包的预设物体(也即是Prefab)。然后选中上面的第一项进行打包成.unity3d格式的文件。如图

 

3.设置名字,路径等(路径很重要,待会加载会用到。)如图:

4.刷新下。你就会看见这个了:

这个就是我们打包后动态加载的内容。

 

5. 现在我来说下怎么动态加载它吧,直接上代码

using UnityEngine;
using System.Collections;
using System.IO;

public class LoadUnity3d : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {

        StartCoroutine(LoadScene());

    }

    // Update is called once per frame
    void Update()
    {

    }

    IEnumerator LoadScene()
    {
        //文件路径,也就是我们打包的那个
        WWW www = new WWW("file:///" + Application.dataPath + "/Bundles/My Prefab.unity3d");
        yield return www;
        Instantiate(www.assetBundle.mainAsset);
    }
}

6.我们再新建一个空物体,讲我们这个脚本托给他,运行,你就能看见我们的预设也加载出来了。

  效果如下:

 


2015-12-29 11:48:35 angelsmiles 阅读数 7375
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

.unity3d格式打包与解包

打包

打包主要用到BuildPipeline.BuildAssetBundle

bt = BuildTarget.StandaloneWindows
string path = EditorUtility.SaveFilePanel("Save Resource", targetDir, saveFileName, "unity3d");
Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets);
BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, options, bt);

解包

解包主要用到WWW

void Start()
{
    StartCoroutine(PreCacheGoodsXmlNodesOld());
}

public static IEnumerator PreCacheGoodsXmlNodesOld()
{
    Object unity3d = Selection.activeObject;
    string url = "";
    WWW www = new WWW(url);
    yield return www;

    AssetBundle assetBundle = null;
    assetBundle = www.assetBundle;
    Object[] objs= assetBundle.LoadAll();
}
2015-08-20 11:53:50 struggle_zcq 阅读数 8121
  • Unity3D入门到精通-(3)Unity资源管理精讲

    本次系列课程的目标是让Unity3D初学者掌握Unity3d的资源管理技术进行了全面介绍,特别对AssetBundle资源如何进行更新,以及加载(依赖资源加载)进行了系统的介绍。 适合对象:Unity初学开发者,Unity中级开发者,网络程序开发者,所有对游戏开发有兴趣的人员。 学习条件:有一定的Unity3D基础,了解C#的基本开发知识。

    4645 人正在学习 去看看 张刚

一、导入外部资源包

1、准备好你学要的资源包.unitypackage文件

2、开始导入资源包

3、选择你下载好的.unitypackage文件

二、导入系统自带资源包

1、Unity3D 5.0以后系统没有自带系统资源包。

2、Unity3D 5.0之前的版本

三、导出资源包

            Unity3D 资源包的导出和导入类似都在Assets菜单栏下的Export Package进行资源包的导出。在这里不过多的讲解。

四、导入3Dmax模型

            用3Dmax软件建和的模型导出.FBX文件,在Unity3D菜单栏里Assets-->Export New Asset即可导入3Dmax模型

unity3d安卓打包教程

阅读数 1019

unity3d安卓打包教程

博文 来自: weixin_44389880
没有更多推荐了,返回首页