原文地址 blog.csdn.net
游戲的換裝, 一般分為 3 種. 換材質(zhì), 骨骼掛接, 共享骨骼. 用的比較多的是骨骼掛接和共享骨骼.
1. 骨骼掛接
沒(méi)有動(dòng)作的骨骼掛接, 適合武器.
有動(dòng)作的骨骼掛接, 適合坐騎.
2. 共享骨骼
共享骨骼, 適合身體部件. 主模型 (身體) 包含整個(gè)骨骼, 部件模型只包含自己部分的骨骼, 應(yīng)用的時(shí)候, 部件模型的骨骼共享主模型的骨骼. 這樣的話, 只需要播放主模型的動(dòng)畫(huà), 部件會(huì)跟著動(dòng).
Unity 的換裝呢, 你要百度一下, 能搜出一堆文章, 方法也是多種多樣. 有參考價(jià)值的卻不多.
比如主流推薦的官方 demo 提供的換裝方式. 合并 mesh, 多此一舉又麻煩.
比如 avatar 的方式 ... 不適合 Legacy 動(dòng)畫(huà)
其實(shí)用以前端游的方式, 共享骨骼就行了, Ogre 引擎直接提供函數(shù) OGRE::shareSkeletonInstanceWith() 來(lái)實(shí)現(xiàn). 而 Unity 引擎沒(méi)有這個(gè)函數(shù), 怎么辦呢, 自己寫一個(gè)唄. 命名我也取一樣的, 表示對(duì) Unity 自己不封裝這個(gè)函數(shù)的鄙視.
// 共享骨骼
public static void ShareSkeletonInstanceWith(SkinnedMeshRenderer selfSkin, GameObject target)
{
Transform[] newBones = new Transform[selfSkin.bones.Length];
for (int i = 0; i < selfSkin.bones.GetLength(0); ++i)
{
GameObject bone = selfSkin.bones[i].gameObject;
// 目標(biāo)的SkinnedMeshRenderer.bones保存的只是目標(biāo)mesh相關(guān)的骨骼,要獲得目標(biāo)全部骨骼,可以通過(guò)查找的方式.
newBones[i] = FindChildRecursion(target.transform, bone.name);
}
selfSkin.bones = newBones;
}
// 遞歸查找
public static Transform FindChildRecursion(Transform t, string name)
{
foreach (Transform child in t)
{
if (child.name == name)
{
return child;
}
else
{
Transform ret = FindChildRecursion(child, name);
if (ret != null)
return ret;
}
}
return null;
}
代碼很簡(jiǎn)單, 原理我再結(jié)合 Unity 仔細(xì)分析下.
第一步 :
假設(shè)整個(gè)模型分兩部分, 身體和翅膀, 身體作為主模型, 翅膀作為部件模型, 身體 30 根骨骼, 翅膀 6 根骨骼, 總數(shù)量 36 根骨骼.
導(dǎo)出身體模型的時(shí)候, 選中身體和整個(gè)骨骼 (注意是整個(gè)骨骼), 這樣身體也包含了翅膀的骨骼.
導(dǎo)出翅膀模型的時(shí)候, 選中翅膀和翅膀骨骼 (翅膀不用導(dǎo)整個(gè)骨骼).
第二步:
模型有哪些骨骼, 可以放入 Unity 查看 root 下面的節(jié)點(diǎn) , 這里有個(gè)注意的地方, 通過(guò) SkinnedMeshRenderer.bones 查看的骨骼數(shù)量總是比通過(guò) root 節(jié)點(diǎn)查看的數(shù)個(gè)數(shù)量少, 因?yàn)?SkinnedMeshRenderer.bones 保存的模型真正用到的骨骼, 而不是整個(gè)骨骼, 比如身體模型的 SkinnedMeshRenderer.bones 只有 30, 而不是 36.
第三步:
平級(jí)掛接 2 個(gè)模型到同一個(gè)父節(jié)點(diǎn)下測(cè)試, 播放身體模型的動(dòng)畫(huà), 身體會(huì)動(dòng), 翅膀不會(huì), 很正常, 因?yàn)閯?dòng)的是身體模型的骨骼, 翅膀模型的骨骼根本就沒(méi)動(dòng). 接下來(lái)把翅膀模型的 6 個(gè)骨骼設(shè)置成身體模型對(duì)應(yīng)的那 6 個(gè)骨骼的 transform, 再播放, 就發(fā)現(xiàn)翅膀也跟著動(dòng)了, 所謂共享, 就是對(duì)應(yīng)的把自己的骨骼設(shè)置成目標(biāo)的骨骼.
函數(shù)調(diào)用很簡(jiǎn)單 ShareSkeletonInstanceWith(翅膀, 身體)