unity人物换装

来源:互联网 发布:小世界网络模型的例子 编辑:程序博客网 时间:2024/04/28 11:11

unity人物换装

人物换装算是游戏中的老梗了,为了美化游戏,为获取更好的游戏体验,很多游戏中可以实现人物换装,还可以给人物更换武器,还要翅膀什么的。总之,能在玩家在体验上 带来很好的效果。
先看下效果图。
这里写图片描述
这个就把一个人物的形象稍微改变了下。为游戏增加些乐趣。

人物的皮肤的制作

首先看下人物皮肤的制作,其实这里美术已经给制作几套模型,我们之给第一套人物模型添加上骨骼,后面的就皮肤都不添加上骨骼了。只有给其加上SkinnedMeshRenderer,且只给添加上一套SkinnedMeshRenderer,不能够添加重复了。

这里就可以去批量生成衣服的prefab了。最好的CreatePrefabInternal()函数就是一句自定义的制作prefab的函数了。

[MenuItem("GameObject/批量生成角色衣服Prefab", false, 0)]    public static void GenerateBodyClothPrefab()    {        if (index >= 1)        {            ResetCreateNormalPrefabByFbxmane();            return;        }        index++;        GameObject[] objs = Selection.gameObjects;        for (int index1 = 0; index1 < objs.Length; index1++)        {            GameObject obj = objs[index1];            if (obj.GetComponent<SkinnedMeshRenderer>() == null)            {                SkinnedMeshRenderer[] skins = obj.GetComponentsInChildren<SkinnedMeshRenderer>();                if (skins != null && skins.Length > 0)                {                    for (int i = 0; i < skins.Length; i++)                    {                        CreateSingleBodySkinPrefab(skins[i].gameObject);                    }                }            }            else            {                CreateSingleBodySkinPrefab(obj);            }        }    } public static void CreateSingleBodySkinPrefab(GameObject skin)    {        if (skin == null) return;        SkinBonesRecord boneRecord = skin.GetComponent<SkinBonesRecord>();        if (boneRecord == null)            boneRecord = skin.AddComponent<SkinBonesRecord>();        boneRecord.RecordBoneNames();        SkinnedMeshRenderer mesh = skin.GetComponent<SkinnedMeshRenderer>();        mesh.receiveShadows = false;        mesh.useLightProbes = false;        mesh.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;        EditorUtility.SetDirty(skin);        string prefabpath = tempPrefabFolderPath + skin.name + "skin.prefab";        CreatePrefabInternal(skin, prefabpath);    }

加载衣服模型

衣服的prefab制作好了,我们在游戏中将其的assetBundle加载进来。这里是通过ShowClothStyle的id将其加载进来的,如果为0的话,就卸载当前的衣服,否则就进去穿衣服的函数。

 public void ShowEquipsFashionCloth(int ShowClothStyle)        {            if (LoadConfigManager.ModelShowContainer.dic.ContainsKey(ShowClothStyle) == false)            {#if UNITY_EDITOR                Debug.LogFormat("不存在时装{0}", ShowClothStyle);#endif                return;            }            #region 衣物模型生成            if (ShowClothStyle != 0)            {                //更换                if (ShowClothStyle != _lastClothStyle && ShowClothStyle != 0)                {           characterGene.ChangeBodyCloth(ShowClothStyle, false);                }            }            else            {                //脱下装备                if (_lastClothStyle != 0)                {                    characterGene.RemoveBodyCloth();                }            }            #endregion            _lastClothStyle = ShowClothStyle;        }

下面的函数会先将旧的衣服的id号保存起来,然后装备里面的号码更新为新的id号。

public void ChangeBodyCloth(int modelid, bool isNgui = false, System.Action doneact = null)    {         int oldclothid = 0;        if (equipsModelCache.ContainsKey("body"))            oldclothid = equipsModelCache["body"];        var model = LoadConfigManager.ModelShowContainer.GetModelShow(modelid);        if (model == null)        {            return;        }        equipsModelCache["body"] = modelid;        GameManager.assetBundleNew.StartCoroutine(_ChangeBodyCloth(modelid, isNgui,oldclothid, doneact));    }

因为要在assetBundle里面加载,所有需要使用协程函数。

 private IEnumerator _ChangeBodyCloth(int clothid, bool isNgui, int oldClothid, System.Action doneact)    {        if (characterRoot == null)        {            Debug.Log("!!! character root is not exist");            yield break;        }        bool isMapRelevant = true;        if (isNgui)            isMapRelevant = true;        GameObject newskinobj = GameManager.objectCacheMgr.SpawnByModelStyle(CacheType.ResName_Model, clothid, true);        if (newskinobj == null)        {            var abinfo = GameManager.assetBundleNew.CreateModelAB(clothid, false, true, isMapRelevant, isNgui);            if (abinfo == null)            {                yield break;            }            while (!abinfo.IsDone)                yield return null;            newskinobj = abinfo.objInst as GameObject;            if (isMapRelevant)              //从缓存池里读取  AssetBundles.AssetBundleManagerNew.AddToMapRelDyUnloadAbInfos(abinfo, isMapRelevant);            else              //放入缓存里面  AssetBundles.ABLoadInfo.Release(abinfo);            if (newskinobj == null)            {                yield break;            }        }        if (destroy)        {       GameManager.objectCacheMgr.CacheExsistGOToCachePool(5, clothid, "", newskinobj, false, false);            yield break;        }        if (!equipsModelCache.ContainsKey("body") || equipsModelCache["body"] != clothid)        {#if UNITY_EDITOR            Debug.LogWarning(clothid + "---download clothid is not cur clothid---- " + "body --" + equipsModelCache["body"]);#endif            GameManager.objectCacheMgr.CacheExsistGOToCachePool(5, clothid, "", newskinobj, false, false);            yield break;        }        //共用一套总骨骼,但是需要更新信息,需要公用下载        if (skins == null)        {            Debug.LogError("no skin");            yield break;        }        SkinnedMeshRenderer newskin = newskinobj.GetComponent<SkinnedMeshRenderer>();        SkinBonesRecord skinbonesRecord = newskinobj.GetComponent<SkinBonesRecord>();        if (newskin == null)        {            Debug.LogError("new skin obj no skinnedmeshrender " + newskinobj.name);            GameObject.Destroy(newskinobj);            yield break;        }        if (skinbonesRecord == null)        {            Debug.LogError("new skin obj no SkinBonesRecord " + newskinobj.name);            GameObject.Destroy(newskinobj);            yield break;        }        List<Transform> bones = new List<Transform>(40);        for (int i = 0; i < skinbonesRecord.BoneNames.Count; i++)        {            for (int j = 0; j < bonetrans.Length; j++)            {                if (boneNames[j] == skinbonesRecord.BoneNames[i])                {                    bones.Add(bonetrans[j]);                    break;                }            }        }        if (normalRoot == null)        {            GameObject.Destroy(newskinobj);            yield break;        }        if (newSkinMesh == null)        {            newSkinMesh = newskin;            newskin.bones = bones.ToArray();            newskinobj.transform.SetParent(normalRoot.transform);            newskinobj.transform.localPosition = Vector3.zero;            newskinobj.transform.localEulerAngles = new Vector3(-90, 0, 0);            newskinobj.transform.localScale = Vector3.one;            baseSkinMesh.gameObject.SetActive(false);            newskinobj.SetActive(true);        }        else        {            newskin.bones = bones.ToArray();            newskinobj.transform.SetParent(normalRoot.transform);            newskinobj.transform.localPosition = Vector3.zero;            newskinobj.transform.localEulerAngles = new Vector3(-90, 0, 0);            newskinobj.transform.localScale = Vector3.one;            baseSkinMesh.gameObject.SetActive(false);            newskinobj.SetActive(true);            if (oldClothid != 0)                GameManager.objectCacheMgr.CacheExsistGOToCachePool(5, oldClothid, "", newSkinMesh.gameObject, false, false);            else                GameObject.DestroyImmediate(newSkinMesh.gameObject);            newSkinMesh = newskin;        }        if (isNgui)        {            NGUITools.SetLayer(newSkinMesh.gameObject, (int)SceneLayer.NGui);        }        else        {            Util.SetObjectLayerWithTagFilter(charobtype, newSkinMesh.gameObject, Const.SceneTags_ModelEffect);        }        ChangeSkinShader();        if (doneact != null)            doneact();    }
原创粉丝点击