参考
Unity-Animator深入系列---录制与回放
学习笔记 --- Unity动画系统
Animator自带了简单的动画录制,回放功能。但可惜的是不支持持久化的数据输出。因而不能作为录像保存。不过这种可以作为竞速,格斗类游戏在结束时经常出现的游戏回放,还是比较有用的。
通过Animator Record 我们可以记录角色在一段时间内所执行的所有动作,并在需要时回放这段动作,Animator会记录动作的执行,过渡,动画参数。进行回放时,Animator的动画状态,状态过渡,动画参数值的改变将在回放中复现。
如果是ApplyRootMotion情况下的动作记录与回放,人物会返回原位置并执行录制好的动作,再次复现整套动作,以及动作产生的位移,角位移。非ApplyRootMotion下的动作记录与回放,人物不会被重置位置,而只是复现动作。
进行回放时,任何对Animator状态机的修改操作均无效(无法修改动画参数,无法进行状态切换)。停止回放时,人物会在当前所在的位置停止回放,并返还Animator的操作权。
一、相关方法
animator.StartRecording(0);//开始记录,需要填入一个int 帧数
//为0一直记录直到调用StopRecording
//大于0记录对应的帧长度,如果记录时间足够长,只会记录最后对应帧长度的动画
animator.StopRecording();//停止记录
animator.StartPlayback();//开始回放
animator.StopPlayback();//停止回放
animator.playbackTime 获取/修改回放的时间点位置
animator.recorderStartTime 获取已记录的动画开始时间点
animator.recorderStopTime 获取已记录的动画结束时间点
如果我们使用animator.StartRecording(0),那么recorderStartTime的值会是0,animator.recorderStopTime是所记录的动画时间长度。而使用animator.StartRecording(int frame),那么recorderStartTime/animator.recorderStopTime是最后frame帧对应的游戏时间点。
二、示例代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RecordAnima : MonoBehaviour
{
Animator animator;
// Start is called before the first frame update
void Start()
{
animator = gameObject.GetComponent<Animator>();
}
bool isRecord=false;//是否在记录中
bool isPlay=false;//是否在回放
float playTime;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
if (!isPlay)
{
if (isRecord)//记录中
{
isRecord = false;
animator.StopRecording();
Debug.Log("停止记录");
Debug.Log("startTime:" + animator.recorderStartTime +
" endTime:" + animator.recorderStopTime);
}
else//未开始记录
{
isRecord = true;
animator.StartRecording(0);//为0一直记录直到调用StopRecording
Debug.Log("开始记录");
}
}
}
if (Input.GetKeyDown(KeyCode.P))
{
if (!isRecord && animator.recorderStopTime > 0 && !isPlay)
{
isPlay = true;
animator.StartPlayback();
animator.playbackTime = animator.recorderStartTime;
Debug.Log("开始回放");
}
else if (isPlay)
{
isPlay = false;
animator.StopPlayback();
Debug.Log("结束回放");
}
}
//播放方法---------------------------------------------------
if (isPlay)
{
playTime = animator.playbackTime;
playTime += Time.deltaTime;//累加时间
if(playTime>animator.recorderStopTime)
{
playTime = animator.recorderStartTime;//循环播放
}
animator.playbackTime = playTime;
}
}
}
动画的回放需要我们在使用了animator.StartPlayback();之后,根据recorderStartTime/animator.recorderStopTime,在Upadte中自行修改playbackTime,累加Time.deltaTime来实现。
三、播放速度(animator.speed)的改变
如果我们需要将animator的播放速度(animator.speed)的改变也记录并实在回放中复现。我们可以通过将速度的数值实时记录在一个动画参数中。当我们进行回放时,由于动画参数的数值会复现,我们可以在播放方法累加Time.deltaTime时与动画参数中获取到的速度数值相乘,从而实现速度改变的记录和回放复现。
同样的思路可以对其他一些需要在回放中复现的属性数值,通过动画参数的记录和引用来实现。
//whenSpeedChange
animator.speed=Speed;
animator.setFloat(SpeedHash,Speed);//将速度实时记录到动画参数中
//播放方法---------------------------------------------------
if (isPlay)
{
playTime = animator.playbackTime;
//与动画参数中获取到的播放速度数值相乘
playTime += Time.deltaTime*animator.getFloat(SpeedHash);
if(playTime>animator.recorderStopTime)
{
playTime = animator.recorderStartTime;//循环播放
}
animator.playbackTime = playTime;
}
网友评论