Unity的蒙皮动画
在UnityEditor,使用SkinnedMeshRenderer承载蒙皮动画
帧动画和骨骼动画,蒙皮动画等等理论,还是得抽空学习一下的,
但要是在不懂原理的情况下(不懂比似懂非懂好点),能做出一个不错的效果吗
主要还是碰到几个痛点,所以研究一下SkinnedMeshRenderer这个组件
- 换装
- 优化后的抖动
- 武器或者坐骑
- 动画连接
分享一个骨骼的可视化工具
在UnityEditor的基础上进行研究,首先还是需要一个骨骼可视化的工具
找了一大圈国内论坛,都是理论(复制,粘贴)居多,不知道应该是可笑呢,还是可笑。
最后还是在一个日本网站找到答案
虽然之前写过一个同样地方式绘制圆球的工具,但还是不如日本小哥写的好
日本小哥连连线也画出来了,还分颜色,甚至还可以打印【挂点】名字,虽然我之前强调不要用OnDrawGizmos,要用OnDrawGizmosSelected;但是这里用的OnDrawGizmos毫无违和,官方的东西也不是全部鸡肋,还是要按实际需求和使用场景进行最优选择
完整代码
using System;
using UnityEngine;
[ExecuteInEditMode]
public class DrawBones : MonoBehaviour
{
#if UNITY_EDITOR
public bool ShowHierarchyAlwyas = true;
public bool ShowSelectedBoneName = true;
public Color BoneColor = Color.white;
public Color SelectedBoneColor = Color.red;
public Color BoneNameColor = Color.cyan;
public float JointSize = 0.0066f;
SkinnedMeshRenderer[] m_Renderers;
GUIStyle m_BoneNameStyle;
private void OnEnable()
{
m_Renderers = GetComponentsInChildren<SkinnedMeshRenderer>();
if (m_Renderers == null || m_Renderers.Length == 0)
{
Debug.LogWarning("No SkinnedMeshRenderer found, script removed");
}
}
void OnDrawGizmos()
{
if (ShowHierarchyAlwyas == false && UnityEditor.Selection.activeGameObject.GetComponentInParent<DrawBones>() != this)
return;
if (m_Renderers == null) return;
if (m_BoneNameStyle == null)
{
m_BoneNameStyle = new GUIStyle (GUI.skin.GetStyle ("Label"));
}
foreach (var render in m_Renderers)
{
var bones = render.bones;
foreach (var B in bones)
{
if (B.parent == null) continue;
bool selfSelected = (UnityEditor.Selection.activeGameObject != null && B.name == UnityEditor.Selection.activeGameObject.name);
bool parentSelected = (UnityEditor.Selection.activeGameObject != null && B.parent.name == UnityEditor.Selection.activeGameObject.name);
if (!ShowSelectedBoneName || selfSelected || parentSelected)
{
m_BoneNameStyle.normal.textColor = BoneNameColor;
UnityEditor.Handles.Label(selfSelected ? B.position : B.parent.position, selfSelected ? B.name : B.parent.name, m_BoneNameStyle);
}
var color = Gizmos.color;
{
if (parentSelected) {
Gizmos.color = SelectedBoneColor;
Gizmos.DrawWireSphere (B.parent.position, JointSize);
Gizmos.color = BoneColor;
}
Gizmos.color = selfSelected ? SelectedBoneColor : BoneColor;
Gizmos.DrawWireSphere (B.position, JointSize); Gizmos.DrawLine(B.position, B.parent.position);
Gizmos.color = color;
}
}
}
}
#endif
}
如何给Mesh绑定骨骼
- 对于Mesh,需要添加boneWeights和 bonePoses(明显,需要和顶点,和uv 1:1对应)
- 对于SkinnedMeshRenderer,需要添加bones
var weights = new BoneWeight[4];
weights[0].boneIndex0 = 0;//确定该顶点(0),使用哪个 Index 的 bone 控制
weights[0].weight0 = 1;
weights[1].boneIndex0 = 0;//确认该顶点(1),使用哪个 Index 的 bone 控制
weights[1].weight0 = 1;
weights[2].boneIndex0 = 1;
weights[2].weight0 = 1;
weights[3].boneIndex0 = 1;
weights[3].weight0 = 1;
mesh.boneWeights = weights;
mesh.bindposes = bindPoses;//这个bindposes主要是一个坐标转置矩阵
赋予骨骼(Bone)动画
Unity基于Dynamic Bone的头发系统三段配置
https://blog.csdn.net/avi9111/article/details/112403647
优化骨骼的方法
勾选了Optimize Game Objects,猜测Native层RootBone的TransformHandle可能还是存在的
可以尝试一下在不勾选Optimize Game Objects的情况下通过代码动态设置,如下图