美文网首页
Unity 动画系列十一 Animator Record 录制与

Unity 动画系列十一 Animator Record 录制与

作者: 合肥黑 | 来源:发表于2021-12-03 14:58 被阅读0次

参考
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;
}

相关文章

网友评论

      本文标题:Unity 动画系列十一 Animator Record 录制与

      本文链接:https://www.haomeiwen.com/subject/gyvozltx.html