To control playback of the Animator in the Scene view of the Unity editor, use the StartPlayback, StopPlayback, StartRecording, and StopRecording methods:
Create an Animator object with a Controller. You can see that the character is in a T-shape. Attached is a new script, EditAnimator, which is empty, as follows:
using UnityEngine;
public class EditAnimator : MonoBehaviour
{
}
Copy the code
Create an editor class for the script, EditAnimatorInspector, as follows:
using UnityEditor;
using UnityEngine;
[CustomEditor( typeof(EditAnimator))]
public class EditAnimatorInspector : Editor
{
/// <summary>
///Current time of slider
/// </summary>
private float m_CurTime;
/// <summary>
///Is it already baked
/// </summary>
private bool m_HasBake;
/// <summary>
///Whether the current state is preview playback
/// </summary>
private bool m_Playing;
/// <summary>
///Current running time
/// </summary>
private float m_RunningTime;
/// <summary>
///Last System time
/// </summary>
private double m_PreviousTime;
/// <summary>
///Total recording time
/// </summary>
private float m_RecorderStopTime;
/// <summary>
///Total length of sliding rod
/// </summary>
private const float kDuration = 30f;
private Animator m_Animator;
private EditAnimator editAnimator { get { return target asEditAnimator; }}private Animator animator
{
get { returnm_Animator ?? (m_Animator = editAnimator.GetComponent<Animator>()); }}void OnEnable()
{
m_PreviousTime = EditorApplication.timeSinceStartup;
EditorApplication.update += inspectorUpdate;
}
void OnDisable()
{
EditorApplication.update -= inspectorUpdate;
}
public override void OnInspectorGUI()
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button( "Bake"))
{
m_HasBake = false;
bake();
}
if (GUILayout.Button( "Play"))
{
play();
}
if (GUILayout.Button( "Stop"))
{
stop();
}
EditorGUILayout.EndHorizontal();
m_CurTime = EditorGUILayout.Slider( "Time:", m_CurTime, 0f, kDuration);
manualUpdate();
}
/// <summary>
///Baking records animation data
/// </summary>
private void bake()
{
if (m_HasBake)
{
return;
}
if (Application.isPlaying || animator == null)
{
return;
}
const float frameRate = 30f;
const int frameCount = ( int)((kDuration * frameRate) + 2);
animator.Rebind();
animator.StopPlayback();
animator.recorderStartTime = 0;
// Start recording the specified number of frames
animator.StartRecording(frameCount);
for (var i = 0; i < frameCount - 1; i++)
{
// New animation state can be triggered at the specified time
if (i == 200)
{
animator.SetTrigger( "Dance");
}
// Record each frame
animator.Update( 1.0 f / frameRate);
}
// Complete the record
animator.StopRecording();
// Enable playback mode
animator.StartPlayback();
m_HasBake = true;
m_RecorderStopTime = animator.recorderStopTime;
}
/// <summary>
///Play a preview
/// </summary>
private void play()
{
if (Application.isPlaying || animator == null)
{
return;
}
bake();
m_RunningTime = 0f;
m_Playing = true;
}
/// <summary>
///Stop preview playback
/// </summary>
private void stop()
{
if (Application.isPlaying || animator == null)
{
return;
}
m_Playing = false;
m_CurTime = 0f;
}
/// <summary>
///Preview updates in playback state
/// </summary>
private void update()
{
if (Application.isPlaying || animator == null)
{
return;
}
if (m_RunningTime > m_RecorderStopTime)
{
m_Playing = false;
return;
}
// Set the playback time and position
animator.playbackTime = m_RunningTime;
animator.Update( 0);
m_CurTime = m_RunningTime;
}
/// <summary>
///Play the current animation frame through the slide bar in the non-preview play state
/// </summary>
private void manualUpdate()
{
if(animator && ! m_Playing && m_HasBake && m_CurTime < m_RecorderStopTime) { animator.playbackTime = m_CurTime; animator.Update(0); }}private void inspectorUpdate()
{
var delta = EditorApplication.timeSinceStartup - m_PreviousTime;
m_PreviousTime = EditorApplication.timeSinceStartup;
if(! Application.isPlaying && m_Playing) { m_RunningTime = Mathf.Clamp(m_RunningTime + (float)delta, 0f, kDuration); update(); }}}Copy the code
The inspector looks like this:
Click on “Bake” and you can see that the character’s pose becomes the first frame of the animation state, as shown below:
Drag the slider to play the current frame, as shown below:
Click “Play” to automatically Play the entire animation, as shown below: