最近整理了一下项目的换装系统,有一些想法,在这里分享一下。
我们的角色拆分了四个部件,头发,身体,腿和脚,对应到gameobject是这样的,000是骨骼根节点。
装备导出是这样的,skinnedmeshrenderer在000同级的子节点上,装备导出也是带骨骼信息的。
第一种实现办法
把装备gameobject挂到角色根节点下,然后通过setactive设置原部件和装备的显隐。
新装备上的skinnedmeshrenderer.bones,需要按照名字在角色的骨骼上找到对应的替换,不然动画就不认了,其他的都很简单不细说了,直接上代码。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ObjSwaper : MonoBehaviour
{
public SkinnedMeshRenderer[] srcEquips = new SkinnedMeshRenderer[4]; // 原来的部件
public SkinnedMeshRenderer[] equips = new SkinnedMeshRenderer[4]; // 预备换的部件
Animation anim = null;
void Start()
{
anim = gameObject.GetComponent<Animation>();
anim.CrossFade("idle1");
}
void Update ()
{
if (Input.GetKeyDown(KeyCode.P))
{
Swap();
}
}
public void Swap()
{
Transform[] transforms = gameObject.GetComponentsInChildren<Transform>(false);
List<Transform> boneList = new List<Transform>();
for (int i = 0 ; i < equips.Length ; ++i)
{
SkinnedMeshRenderer smr = null;
if (equips[i] != null)
{
smr = equips[i];
equips[i].transform.parent.gameObject.SetActive(true);
srcEquips[i].gameObject.SetActive(false);
}
else
{
smr = srcEquips[i];
srcEquips[i].gameObject.SetActive(true);
}
boneList.Clear();
foreach (Transform bone in smr.bones)
{
foreach (Transform item in transforms)
{
if (item.name != bone.name)
continue;
boneList.Add(item);
break;
}
}
smr.bones = boneList.ToArray();
smr.rootBone = srcEquips[i].rootBone;
}
}
}