Unity 5.x BuildAssetBundles 角色换装 加载ab包 资源管理 根据部件组合完整角色

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

/// <summary>
/// Assetbundles 资源管理类
/// </summary>
public class ManageAssets : MonoBehaviour
{
    private static ManageAssets instance = null;
    public static ManageAssets Instace() { return instance; }
    private string url;
    private string manifestName;
    /// <summary>
    /// 已解压的Asset列表 [prefabPath, asset]
    /// </summary>
    private Dictionary<string, Object> dicAsset = new Dictionary<string, Object>();
    /// <summary>
    /// "正在"加载的资源列表 [prefabPath, www]
    /// </summary>
    private Dictionary<string, WWW> dicLoadingReq = new Dictionary<string, WWW>();


    void Awake()
    {
        instance = this;
    }
    void Start()
    {
        InitializeAssetdataPath();//获取平台资源路径
        //角色基本骨架 + 部件 string
        //sName = "male_charactorbase|male_eyes|male_face-1|male_hair-1|male_pants-1|male_shoes-1|male_top-1";
        //sName = "male_charactorbase|male_eyes|male_face-2|male_hair-2|male_pants-2|male_shoes-2|male_top-2";

        //for (int i = 0; i < sSps.Length; i++)
        //{
        //    assetname = sSps[i];//根据名字加载资源
        //    LoadAsync(assetname);
        //}

        //StartCoroutine(isConfigReady(sName));//判断是否加载完成
    }
    //组合生成角色蒙皮网格信息
    //StartCoroutine 在他之后,判断加载完成后,获取根骨骼+部件组合的模型,把根骨骼传入即可组合生成模型
    public void Generate(GameObject root)
    {
        float startTime = Time.realtimeSinceStartup;

        // The SkinnedMeshRenderers that will make up a character will be
        // combined into one SkinnedMeshRenderers using multiple materials.
        // This will speed up rendering the resulting character.
        List<CombineInstance> combineInstances = new List<CombineInstance>();
        List<Material> materials = new List<Material>();
        List<Transform> bones = new List<Transform>();
        Transform[] transforms = root.GetComponentsInChildren<Transform>();
        //遍历加载
        foreach (SkinnedMeshRenderer smr in root.GetComponentsInChildren<SkinnedMeshRenderer>(true))
        {
            if (!smr.name.Contains("charactorbase"))
            {
                // As the SkinnedMeshRenders are stored in assetbundles that do not
                // contain their bones (those are stored in the characterbase assetbundles)
                // we need to collect references to the bones we are using
                foreach (Transform bone in smr.bones)
                {
                    foreach (Transform transform in transforms)
                    {
                        if (transform.name != bone.name) continue;
                        bones.Add(transform);
                        break;
                    }
                }

                CombineInstance ci = new CombineInstance();
                ci.mesh = smr.sharedMesh;
                combineInstances.Add(ci);
                materials.AddRange(smr.materials);

                Object.Destroy(smr.gameObject);
            }

        }

        // Obtain and configure the SkinnedMeshRenderer attached to
        // the character base.
        SkinnedMeshRenderer r = root.GetComponent<SkinnedMeshRenderer>();
        r.sharedMesh = new Mesh();
        r.sharedMesh.CombineMeshes(combineInstances.ToArray(), false, false);
        r.materials = materials.ToArray();
        r.bones = bones.ToArray();

        //Debug.Log("Generating character took: " + (Time.realtimeSinceStartup - startTime) * 1000 + " ms");
    }
    //判断是否加载完成
    public bool CongigReady(string[] sSps)
    {
        //string[] sSps = sUpdateString.Split('|');
        for (int i = 0; i < sSps.Length; i++)
        {
            if (!IsResLoaded(sSps[i].Trim()))
            {
                return false;
            }
        }

        return true;
    }

    //获取资源对象
    public Object GetResource(string name)
    {
        Object obj = null;
        if (dicAsset.TryGetValue(name, out obj) == false)
        {
            Debug.Log("<GetResource Failed> Res not exist, res.Name = " + name);
            if (dicLoadingReq.ContainsKey(name))
            {
                Debug.Log("<GetResource Failed> The res is still loading");
            }
        }
        return obj;
    }

    // 加载
    public void LoadAsync(string name)
    {
        LoadAsync(name, typeof(GameObject));
    }

    //加载
    public void LoadAsync(string name, System.Type type)
    {
        // 如果已经下载,则返回
        if (dicAsset.ContainsKey(name))
            return;

        // 如果正在下载,则返回
        if (dicLoadingReq.ContainsKey(name))
            return;

        // 如果没下载,则开始下载
        StartCoroutine(AsyncLoadCoroutine(name, type));
    }
    //开启WWW加载资源
    private IEnumerator AsyncLoadCoroutine(string name, System.Type types)
    {
        string assetBundleName = name + ".assetbundle";

        WWW www = new WWW(url + assetBundleName);
        dicLoadingReq.Add(name, www);
        yield return www;

        if (!string.IsNullOrEmpty(www.error))
        {
            goPath.text = www.error;
            Debug.Log(www.error);
        }
        else
        {
            AssetBundle ab = www.assetBundle;
            foreach (string n in ab.GetAllAssetNames())
            {
                AssetBundleRequest req = ab.LoadAssetAsync(n, types);
                yield return req;
                dicAsset.Add(name, req.asset);
                dicLoadingReq.Remove(name);
            }
            ab.Unload(false);
        }
        www.Dispose();
    }
    //是否正在加载
    public bool IsResLoading(string name)
    {
        return dicLoadingReq.ContainsKey(name);
    }
    //判断是否加载完毕
    public bool IsResLoaded(string name)
    {

        if (name != "")
        {
            return dicAsset.ContainsKey(name);
        }
        else
        {
            return true;
        }
    }
    //资源存放路径:streamingAssetsPath文件夹下面
    void InitializeAssetdataPath()
    {
#if UNITY_EDITOR
        url = "file://" + Application.streamingAssetsPath + "/assetbundles/Windows/";
        manifestName = "Windows";
#elif UNITY_ANDROID
        url = Application.streamingAssetsPath + "/assetbundles/Android/";
        manifestName ="assetbundles"; 

#endif
    }
}













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值