unity人物换装

Posted xiaogeformax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity人物换装相关的知识,希望对你有一定的参考价值。

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();
    

以上是关于unity人物换装的主要内容,如果未能解决你的问题,请参考以下文章

Unity3d 换装 之 模型动画分离

Scratch换装小游戏 蓝桥杯STEMA考试Scratch编程真题和答案解析

世界传说 换装迷宫2 所有人物及所有技能及奖励技能 && 传说系列各秘奥技和台词

Unity 实现 角色的换装

Unity3D游戏开发之换装系统的实现

Unity3D换装系统