引言
最近项目需要开发换装系统,做了一些前期的调研。换装系统主要应用与MMORPG游戏中,除了常规的换衣服,发型,翅膀之类的,现在一些次时代的MMORPG游戏加入了捏脸,改变五官等比较复杂的换装系统。本次介绍通过
替换Mesh数据来实现换装的方法。
期望效果
模型1
模型2
期望可以在游戏运行时将模型1的外观替换为模型2的外观。
实现原理
通过收集模型2中对应的mesh信息,替换掉模型1中的mesh信息。
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class ChangeFoot : MonoBehaviour {
private SkinnedMeshRenderer oldSmr = null;
private SkinnedMeshRenderer newSmr = null;
private Object oldObj = null;
private Object newObj = null;
private GameObject oldInstance = null;
private GameObject newInstance = null;
void OnGUI()
{
if (GUI.Button(new Rect(00, 0, 100, 30), "Change Foot"))
{
ChangeFeet();
}
}
void ChangeFeet()
{
//加载替换对象的资源文件
newObj = Resources.Load("Prefab/newFoot");
newInstance = Instantiate(newObj) as GameObject;
oldSmr = gameObject.GetComponentInChildren<SkinnedMeshRenderer>();
newSmr = newInstance.GetComponentInChildren<SkinnedMeshRenderer>();
Transform[] oldBones = gameObject.GetComponentsInChildren<Transform>();
//Transform[] oldBones = oldSmr.bones; //模型会出现错乱
Debug.Log("oldBones.Length: " + oldBones.Length);
Transform[] newBones = newSmr.bones;
Debug.Log("newBones.Length: " + newBones.Length);
//对骨骼进行重新排序
List<Transform> bones = new List<Transform>();
foreach (Transform bone in newBones)
{
foreach (Transform oldBone in oldBones)
{
if (bone != null && oldBone != null)
{
if (bone.name != oldBone.name)
{
continue;
}
bones.Add(oldBone);
}
}
}
//替换Mesh数据
oldSmr.bones = bones.ToArray();
oldSmr.sharedMesh = newSmr.sharedMesh;
oldSmr.sharedMaterial = newSmr.sharedMaterial;
//删除无用的对象
GameObject.DestroyImmediate(newInstance);
GameObject.DestroyImmediate(newSmr);
}
}
运行结果:
参考资料:
资源文件来自: