Unity 3D Avatar换装系统 SkinnedMeshRenderer皮肤渲染
2017-02-17 11:28
555 查看
版本:unity 5.4.1 语言:C#
参考了《Unity3D 实战核心技术详解》,我把换装系统的一个核心技术记录一下,本人虽然是在U3D开发,不过没有真正接触到这样的技术,感觉比较遗憾,这里做个入门,万一以后有相关需求的话,心里也有底。
首先说下人物模型的构成:除去动画以外,名称中有Bip字样的节点都是骨骼、其他的就是我们能看的到的皮肤。
骨骼就是一些Transfrom,没有其他的组件,它们会根据动画的要求进行运动。
而皮肤上关键的一个组件是SkinnedMeshRenderer,它关联了3样东西:1.网格;2.骨骼;3.材质。所以我们只要在代码中改变以上三样东西,就能替换模型上的部件。
来看一下具体的代码吧:
例子上核心的东西也没什么吧,不过说实话真正看到这个的代码的时候,我才知道Bip是有什么用,而SkinnedMeshRenderer需要骨骼、材质、Mesh才能发挥作用。
参考了《Unity3D 实战核心技术详解》,我把换装系统的一个核心技术记录一下,本人虽然是在U3D开发,不过没有真正接触到这样的技术,感觉比较遗憾,这里做个入门,万一以后有相关需求的话,心里也有底。
首先说下人物模型的构成:除去动画以外,名称中有Bip字样的节点都是骨骼、其他的就是我们能看的到的皮肤。
骨骼就是一些Transfrom,没有其他的组件,它们会根据动画的要求进行运动。
而皮肤上关键的一个组件是SkinnedMeshRenderer,它关联了3样东西:1.网格;2.骨骼;3.材质。所以我们只要在代码中改变以上三样东西,就能替换模型上的部件。
来看一下具体的代码吧:
public Transform target; // 目标的模型,要求其骨骼已经存在 public Transform source; // 源模型,所有的可以替换的部件都在这上面 // 模型资源,对应上面的source Dictionary<string, Dictionary<string, Transform>> data = new Dictionary<string, Dictionary<string, Transform>>(); // 目标骨架,对应上面的target Transform[] hips; // 目标皮肤,替换这里面的内容就行了 Dictionary<string, SkinnedMeshRenderer> targetSmr = new Dictionary<string, SkinnedMeshRenderer>(); // 初始化时的皮肤 string[,] avatarStr = new string[,] { { "coat", "003" }, { "hair", "003" }, { "pant", "003" }, { "hand", "003" }, { "foot", "003" }, { "head", "003" } }; // Use this for initialization void Start() { // 获取资源的所有皮肤 SkinnedMeshRenderer[] parts = source.GetComponentsInChildren<SkinnedMeshRenderer>(); // 初始化data,将资源添加到Dictionary容器中 foreach (SkinnedMeshRenderer part in parts) { string[] partName = part.name.Split('-'); if (!data.ContainsKey(partName[0])) { data.Add(partName[0], new Dictionary<string, Transform>()); // 初始化targetSmr,添加骨架上的皮肤类,但当前的皮肤类内容是空的 GameObject partObj = new GameObject(); partObj.name = partName[0]; partObj.transform.parent = target; partObj.transform.localPosition = part.transform.localPosition; partObj.transform.localRotation = part.transform.localRotation; targetSmr.Add(partName[0], partObj.AddComponent<SkinnedMeshRenderer>()); } data[partName[0]].Add(partName[1], part.transform); } // 初始化hips,获取所有的骨骼,在Unity已经添加 hips = target.GetComponentsInChildren<Transform>(); // 初始化皮肤 int length = avatarStr.GetLength(0); for (int i = 0; i < length; ++i) { changeMesh(avatarStr[i, 0], avatarStr[i, 1]); } } // 改变部件 public void changeMesh(string part, string item) { SkinnedMeshRenderer smr = data[part][item].GetComponent<SkinnedMeshRenderer>(); //获取当前要替换的皮肤,这是源 // 获取target上与source对应的骨骼,这边千万不能直接把骨骼赋值进去了 List<Transform> bones = new List<Transform>(); foreach (Transform bone in smr.bones) { foreach (Transform hip in hips) { if (hip.name != bone.name) { continue; } bones.Add(hip); break; } } // 这边是目标,进行替换 targetSmr[part].sharedMesh = smr.sharedMesh; //替换皮肤 targetSmr[part].bones = bones.ToArray(); //替换骨骼 targetSmr[part].materials = smr.materials; //替换材质 }
例子上核心的东西也没什么吧,不过说实话真正看到这个的代码的时候,我才知道Bip是有什么用,而SkinnedMeshRenderer需要骨骼、材质、Mesh才能发挥作用。
相关文章推荐
- Unity 3D Avatar换装系统
- unity, SkinnedMeshRenderer.updateWhenOffscreen
- unity 合并skinnedMeshRenderer中遇到的一个大坑
- 在Unity 5中优化SkinnedMeshRenderer
- unity, SkinnedMeshRenderer.bones[i]不能直接赋值
- 关于Unity中Skinned Mesh Renderer中Quality中的坑
- Unity SkinnedMesh 换装
- unity换装,SkinnedMeshRender
- Unity 3D换装系统教程/Demo
- Unity Avatar动画系统
- [Unity实战]详解换装系统(三)
- [Unity实战]换装系统的原理
- Unity 3D 创建Mesh(一)
- [Unity实战]详解换装系统(四)
- Unity 3D 粒子系统(1)
- OGRE3D 渲染系统线程化
- cocos2d-x实现3D模型的换装系统的研究
- Unity 3D 粒子系统的一点经验
- Unity 3D 创建Mesh(二)
- Unity 3D 动态创建对象,并渲染贴图,动态添加删除脚本