https://zhuanlan.zhihu.com/p/71544395
一般都是三种中选一种
1 换模型面部贴图,UV动画实现
优点:换贴图的话,如果做得精细,可以表现得内容特别多,表情丰富,2D、3D都可以使用
缺点:贴图内存占用是个问题,美术制作麻烦,还需要代码逻辑实现
2 面部骨骼动画
缺点:动作美术工作量问题,权重分配受限,可能没啥突出优点,都没在网上找到过类似例子......
3 BlendShape表情
优点:美术控制Morphing参数,每个表情额外只占用一个动画信息,10-20K,表情也可以很精细,导出表情动画不需要代码,动画状态机控制
缺点:2D不能用
综上,选用了BlendShape表情,网上已有关于BlendShape表情的文章,都是代码来控制SkinnedMeshRenderer上BlendShape的权重,表现很僵硬。所以,为了要生动的表情动画,本文直接使用美术导出的表情动画,而不是程序控制,这样就会完美还原美术制作的表情动画。
先放一张效果图,希望大家多多关注我们公司的游戏《王牌御史》~
代码很少,下面直接上教程。
BlendShape表情,主要工作量在美术,美术制作好表情动画之后,导入Unity中按照下面设置播放即可
美术方面:美术额外导出一个FBX,带有蒙皮信息、骨骼动画只保留一个造型、单独面部的动画信息(Morphing)
经过测试,只有美术网格、骨骼、蒙皮、Morphing动画一起导出来的Fbx才能保留表情动画信息
导入到Unity中,基础模型要开启Import BlendShape
对应的面部SkinnedMeshRenderer上会多出BlendShape的配置(调整这些值就可以看到表情变化了)
ModelImporter
SkinnedMeshRenderer
按照美术的制作,裁切动画片段,下面的每一个动画片段,就包含了美术制作的表情动画
动画导入拆分
也可以每个表情动画导出一个fbx,根据项目选择一个FBX然后拆分多个动画 或 每个动画单独一个FBX 都可以
双层状态机:为了面部表情独立出来,不与基础动作绑定死,可以通过代码逻辑自由组合播放
左图第一层控制角色动作,基础骨骼动画(跑、跳、肢体的害羞动作等)
右图第二层控制表情动画,表情动画(面部表情,开心 难过 眨眼 等)
基础动画状态机
表情动画层
对于上面第二层状态机,需要有一点注意一下,小齿轮中Mask,需要制定一个AvatarMask,受这层状态机影响的骨骼或蒙皮
AvatarMask(动画遮罩):可以控制哪部分骨骼或蒙皮受影响
FaceLayer中的Mask只需要开启面部蒙皮,这样只有面部受第二层状态机影响
在Project试图 右键 然后 Create/Avatar Mask 可以创建AvatarMask,然后指定对应Fbx中的avatar,就可以导入模型骨骼蒙皮信息
设置如下图,只需要选择面部的蒙皮
控制播放的逻辑,播放基础动作的时候,配套播一个面部表情,这里可以根据项目情况,角色动作和表情自行组合
animator.Play(actionState, layerIndex); 可以播放指定层的动画
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayAnimation : MonoBehaviour {
private Animator animator;
private int faceLayer;
private void Awake()
{
animator = GetComponent();
faceLayer = animator.GetLayerIndex("FaceLayer");
}
private void OnGUI()
{
GUILayout.BeginVertical();
if (GUILayout.Button("表情1", GUILayout.Width(20.0f), GUILayout.Height(20.0f)))
{
//播放基础动作
animator.Play("tr1");
//通知指定播放第二层的表情动作
animator.Play("Emojitr1", faceLayer);
}
if (GUILayout.Button("表情2", GUILayout.Width(20.0f), GUILayout.Height(20.0f)))
{
animator.Play("tr2");
animator.Play("Emojitr2", faceLayer);
}
GUILayout.EndVertical();
}
}
Over~
2019-8-1更新
上面的这种方式由美术制作表情动画导入,动画信息中可能会产生多余的骨骼动画信息,所以这里通过导入器导入动画FBX的时候,动态删除多余的骨骼信息,参考另一个文章
范世青:Unity通过导入器优化动画关键帧数据zhuanlan.zhihu.com
另一个偶现的BUG,是表情很奇怪,发现问题是播放表情动画的时候SkinnedMeshRenderer上的BlendShape某一个权重超过了100,但是美术制作的时候确定最大不会超过100
最后发现是动画导入器的ResampleCurve导致的,重采样动画曲线,使某一小段曲线采样超过了100,导致表情错误,参考另一篇文章
范世青:关于UnityAnimation ResampleCurves的优缺点分析
zhuanlan.zhihu.com
取消掉导入器的ResampleCurve解决
编辑于 2019-08-01