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人物换装的主要内容,如果未能解决你的问题,请参考以下文章
Scratch换装小游戏 蓝桥杯STEMA考试Scratch编程真题和答案解析