动画播放器(自开发版)

21 篇文章 1 订阅
17 篇文章 0 订阅
文章介绍了如何在Unity中使用CustomEditor实现播放器的控制功能,如播放、倒带、暂停等,并展示了移动脚本如何处理动画进度和位置变化的逻辑,包括使用曲线插值进行平滑变换。
摘要由CSDN通过智能技术生成

播放界面实例:
请添加图片描述
图中的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;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值