播放界面实例:
图中的MainDirector 为播放器主驱动脚本,AnimatroMove 为移动的数据存储脚本
播放器Editor.cs
using UnityEngine;
using UnityEditor;
namespace Redmoon.Animator
{
[CustomEditor(typeof(RmAnimatorMainDirector), true)]
[CanEditMultipleObjects]
public class RmAnimationMainDirctorEditor : Editor
{
private SerializedProperty Target, PlaySpeed, IsAwakePlay, timeScaleTime, curPlayModel,MaxTime;
protected void OnEnable()
{
FetchProperties();
}
protected void FetchProperties()
{
Target = serializedObject.FindProperty("target");
PlaySpeed = serializedObject.FindProperty("playSpeed");
IsAwakePlay = serializedObject.FindProperty("autoPlay");
timeScaleTime = serializedObject.FindProperty("timeScaleTime");
//Curve = serializedObject.FindProperty("Curve");
curPlayModel = serializedObject.FindProperty("playMode");
MaxTime = serializedObject.FindProperty("_maxAnimationTime");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
Inspect();
if (GUI.changed)
serializedObject.ApplyModifiedProperties();
}
private float progress;
public void Inspect()
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("|>播放", GUILayout.MinWidth(30)))
{
((RmAnimatorMainDirector)target).EmpPlay();
}
if (GUILayout.Button("|>倒播", GUILayout.MinWidth(30)))
{
((RmAnimatorMainDirector)target).EmpBack();
}
if (GUILayout.Button("|<<重置", GUILayout.MinWidth(30)))
{
((RmAnimatorMainDirector)target).EmpReset();
}
if (GUILayout.Button("||停止", GUILayout.MinWidth(30)))
{
((RmAnimatorMainDirector)target).EmpPause();
}
if (GUILayout.Button(">>继续", GUILayout.MinWidth(30)))
{
((RmAnimatorMainDirector)target).EmpContinue();
}
if (GUILayout.Button(">下一帧", GUILayout.MinWidth(30)))
{
((RmAnimatorMainDirector)target).EmpNextFrame();
}
if (GUILayout.Button(">>|完成", GUILayout.MinWidth(30)))
{
((RmAnimatorMainDirector)target).EmpFinish();
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("进度条预览", GUILayout.MinWidth(30));
var progress_ = progress / 200f;
var curTime = MaxTime.floatValue * progress_;
GUILayout.Label($"当前进度{System.Math.Round(progress_, 2)}", GUILayout.Width(80));
GUILayout.Label($"时间:{System.Math.Round(curTime, 2)}s/{MaxTime.floatValue}s");
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
float newProgress = GUILayout.HorizontalSlider(progress, 0, 200f, GUILayout.MinHeight(30), GUILayout.MinWidth(200));
if (newProgress != progress)
{
((RmAnimatorMainDirector)target).EmpTargetProgress(newProgress/200f);
progress = newProgress;
}
//GUILayout.EndVertical();
GUILayout.EndHorizontal();
//EditorGUILayout.PropertyField(Target);
//EditorGUILayout.PropertyField(PlaySpeed);
//EditorGUILayout.PropertyField(IsAwakePlay);
//EditorGUILayout.PropertyField(timeScaleTime);
//EditorGUILayout.PropertyField(curPlayModel);
}
}
}
移动脚本数据储存逻辑
using Foundation;
using UnityEngine;
namespace Redmoon.Animator
{
public class RmAnimatorMove : RmAnimatorBase
{
public CurveWrapper X = new CurveWrapper("X");
public CurveWrapper Y = new CurveWrapper("Y");
public CurveWrapper Z = new CurveWrapper("Z");
public Vector3 InitialPosition, TargetPosition;
public bool UseWorldSpacePosition = false;
public bool UseInitPosition = true;
private Vector3 startPosition;
public void SetTargetPosition()
{
}
private bool isInit = false;
#if UNITY_EDITOR
[ContextMenu("#InitPosition")]
private void InitPosition()
{
if (Target != null)
{
InitialPosition = Target.transform.localPosition;
}
}
[ContextMenu("#TargetPosition")]
private void TargetPos()
{
if (Target != null)
{
TargetPosition = Target.transform.localPosition;
}
}
#endif
protected override void OnAnimationClipBegin()
{
base.OnAnimationClipBegin();
InitPos();
isInit = true;
}
private void InitPos()
{
if (Target == null)
return;
if (UseWorldSpacePosition)
startPosition = Target.transform.position;
else
startPosition = Target.transform.localPosition;
}
protected override void OnProgress(float pProcess)
{
if (Target == null)
return;
if (UseInitPosition == false && isInit == false)
{
OnAnimationClipBegin();
}
var sourcePosition = UseInitPosition ? InitialPosition : startPosition;
var curPosition = UseWorldSpacePosition ? Target.transform.position : Target.transform.localPosition;
if (X.Enable)
curPosition.x =
sourcePosition.x.Lerp(TargetPosition.x, RmAnimatorUtility.GetCurveValue(X.Curve, pProcess));
if (Y.Enable)
curPosition.y =
sourcePosition.y.Lerp(TargetPosition.y, RmAnimatorUtility.GetCurveValue(Y.Curve, pProcess));
if (Z.Enable)
curPosition.z =
sourcePosition.z.Lerp(TargetPosition.z, RmAnimatorUtility.GetCurveValue(Z.Curve, pProcess));
SetTargetValue(curPosition);
}
private void SetTargetValue(Vector3 pValue)
{
if (Target != null)
{
if (UseWorldSpacePosition)
Target.transform.position = pValue;
else
Target.transform.localPosition = pValue;
}
}
public void SetTargetWorldPos(Vector3 worldPos)
{
UseWorldSpacePosition = true;
TargetPosition = worldPos;
}
}
}