需求分析: Unity中在人物播放某个动画时往往伴随着动画音效的播放,或则是人物打击的粒子特效播放。
- 解决方案一:早期这种需求的处理方案是在Animatio(Ctrl+6)动画中添加Event事件,然后填写注册的方法名,Unity会在挂载该动画的物体上查找该方法,在动画播放到定义事件的那一帧时,会执行该方法,我们通常将动画播放的音效或则粒子特效在该方法中实现,不过Unity5之后,这个方法就不好用了,这些事件被Unity官方定义成了一系列的系统事件,不能够自定义使用了。
- 解决方案二:其实我们要实现上述需求还可以使用StateMachineBehaviour,通过定义一个类继承自StateMachineBehaviour并重写其中的方法,如:OnStateEnter(动画进入该状态时使用),OnStateExit(动画离开该状态时使用),OnStateUpdate(动画在该状态每一帧调用)等等。
这里我们使用解决方案二举例,Unity版本使用的是Unity2018.3.14版本,在人物疾跑状态下实现人物残影。
这里放上实现的效果图:
实现方法
创建RunBehaviour脚本继承自StateMachineBehaviour并重写其中的
OnStateEnter,OnStateExit,OnStateUpdate方法;在此脚本中实现人物疾跑状态下的残影,之后将脚本挂载Animator Controller中的Run动画状态上,操作如下:
RunBehavior脚本挂载Run动画状态上,如上图
RunBehavior完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RunBehaviour : StateMachineBehaviour
{
public float fadeSpeed = 3;
public float createSpeed = 5;
private float previousTime = 0;
private SkinnedMeshRenderer[] meshRenders;
private MeshFilter[] meshFilters;
private List<MeshInfo> meshInfoList = new List<MeshInfo>();
struct MeshInfo
{
public Mesh mesh;
public Matrix4x4 matrix_PR;
public Material material;
};
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
Debug.Log(animator.gameObject.name);
meshRenders = animator.gameObject.GetComponentsInChildren<SkinnedMeshRenderer>();
meshFilters = animator.gameObject.GetComponentsInChildren<MeshFilter>();
}
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
meshInfoList.Clear();
}
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{