【unity】编辑模式预览Animator动作,2种实现。 其中一种 playback模式是Cinema Director用的会使Unity Crash

一、环境

Unity 5.5.2 、Cinema Director v1.4.5.4 


二、问题

美术用 Director 做CutScene动画时, 某一个角色动作时间线上,播放多个动作, 预览模式,拖动线的时候,Unity基本会100%Crash

如上图拖到类似位置就会闪退(如果一个Track只有一个动作 则不会)

有2中Crash:

========== OUTPUTING STACK TRACE ==================
0x000000014073DCB9 (Unity) AnimationClipPlayable::SetClip
0x0000000141650663 (Unity) mecanim::statemachine::StartState
0x0000000141651118 (Unity) mecanim::statemachine::EvaluateStateMachine
0x0000000140740D9D (Unity) AnimatorControllerPlayable::UpdateGraph
0x0000000140684F61 (Unity) Animator::EvaluateController
0x00000001406E12BD (Unity) Animator::UpdateAvatars
0x00000001406E207C (Unity) Animator::UpdateWithDelta
0x000000004F0EF2A5 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.Animator:Update (single)
0x000000004F0F9885 (Mono JIT Code) [C:\work\mmo3d_client\mmo3d\Assets\Cinema Suite\Cinema Director\System\Runtime\TrackGroups\CharacterTrackGroup.cs:154] CinemaDirector.CharacterTrackGroup:Update () 
0x000000004A527370 (Mono JIT Code) (wrapper delegate-invoke) UnityEditor.EditorApplication/CallbackFunction:invoke_void__this__ ()
0x000000004A526FA3 (Mono JIT Code) [C:\buildslave\unity\build\artifacts\generated\common\editor\EditorApplicationBindings.gen.cs:207]


========== OUTPUTING STACK TRACE ==================
0x000000014164E5FC (Unity) mecanim::statemachine::EvaluateState
0x000000014165121E (Unity) mecanim::statemachine::EvaluateStateMachine
0x0000000140740D9D (Unity) AnimatorControllerPlayable::UpdateGraph
0x0000000140684F61 (Unity) Animator::EvaluateController
0x00000001406E12BD (Unity) Animator::UpdateAvatars
0x00000001406E207C (Unity) Animator::UpdateWithDelta
0x00000000361ECC45 (Mono JIT Code) (wrapper managed-to-native) UnityEngine.Animator:Update (single)
0x000000002F7F06AA (Mono JIT Code) [C:\work\mmo3d_client\mmo3d\Assets\Cinema Suite\Cinema Director\System\Runtime\TrackGroups\CharacterTrackGroup.cs:175] CinemaDirector.CharacterTrackGroup:UpdateTrackGroup (single,single) 
0x00000000360F6B3A (Mono JIT Code) [C:\work\mmo3d_client\mmo3d\Assets\Cinema Suite\Cinema Director\System\Runtime\Cutscene.cs:212] CinemaDirector.Cutscene:UpdateCutscene (single) 
0x00000000361022BC (Mono JIT Code) [C:\work\mmo3d_client\mmo3d\Assets\Cinema Suite\Cinema Director\System\Runtime\Cutscene.cs:266] CinemaDirector.Cutscene:ScrubToTime (single) 
0x0000000036101E4C (Mono JIT Code) [C:\work\mmo3d_client\mmo3d\Assets\Cinema Suite\Cinema Director\System\Editor\DirectorWindow.cs:256] DirectorWindow:directorControl_ScrubCutscene (object,CinemaDirectorArgs) 
0x0000000031995D93 (Mono JIT Code) DirectorControl:updateTimelineHeader (UnityEngine.Rect,UnityEngine.Rect)
0x0000000031988094 (Mono JIT Code) DirectorControl:OnGUI (UnityEngine.Rect,CutsceneWrapper)

三、编辑模式实现动作预览并播放指定时间方式1
类似这种方式:
http://blog.csdn.net/akof1314/article/details/45226945
Cinema Director里也是用这种方式,控制一个动作这个方案没问题。
包括这个:http://bbs.cgwell.com/thread-34313-1-2.html 也是一样实现原理。


Cinema Director  是在 CharacterTrackGroup.cs实现 编辑模式动作拖动预览的。核心就是用Animator的录制 回放

录制
            float frameRate = 30;
            int frameCount = (int)((Cutscene.Duration * frameRate) + 2);
            animator.StopPlayback();
            animator.recorderStartTime = 0;
            animator.StartRecording(frameCount);
            base.SetRunningTime(0);
            for (int i = 0; i < frameCount-1; i++)
            {
                TimelineTrack[] tracks = GetTracks();
                for (int j = 0; j < tracks.Length; j++)
                {
                    if (!(tracks[j] is DialogueTrack))
                    {
                        tracks[j].UpdateTrack(i * (1.0f / frameRate), (1.0f / frameRate));
                    }
                }
                animator.Update(1.0f / frameRate);
            }
            animator.recorderStopTime = frameCount * (1.0f / frameRate);
            animator.StopRecording();
            animator.StartPlayback();
更新时:
                    animator.playbackTime = time;
                    animator.Update(0);
播放指定时间动作。
目前关键就是多个动作时,播放到后面几个动作 animator.Update(0)很容易挂掉。

四、编辑模式实现动作预览并播放指定时间方式2
参考了:https://www.cnblogs.com/chiguozi/p/6862571.html
就是用 AnimationMode.SampleAnimationClip 
就是找到对用的 AnimationClip 然后让其sample指定时间的动作。


五、优化了
Cinema Director的代码, 换成用 方式2 预览动作, 实测没有发生Crash
1. CharacterTrackGroup.cs
/* */ 部分是shan
#if UNITY_EDITOR  部分新增的

// Cinema Suite
using CinemaDirector.Helpers;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace CinemaDirector
{
    /// <summary>
    /// The character track group is a type of actor group, specialized for humanoid characters.
    /// </summary>
    [TrackGroupAttribute("Character Track Group", TimelineTrackGenre.CharacterTrack)]
    public class CharacterTrackGroup : ActorTrackGroup, IRevertable, IBakeable
    {
        // Options for reverting in editor.
        [SerializeField]
        private RevertMode editorRevertMode = RevertMode.Revert;

        // Options for reverting during runtime.
        [SerializeField]
        private RevertMode runtimeRevertMode = RevertMode.Revert;

        // Has a bake been called on this track group?
        private bool hasBeenBaked = false;

        /// <summary>
        /// Bake the Mecanim preview data.
        /// </summary>
        public void Bake()
        {
            if (Actor == null || Application.isPlaying) return;
            Animator animator = Actor.GetComponent<Animator>();
            if (animator == null)
            { return; }

            AnimatorCullingMode cullingData = animator.cullingMode;
            animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;

            List<RevertInfo> revertCache = new List<RevertInfo>();

            // Build the cache of revert info.
            MonoBehaviour[] mb = this.GetComponentsInChildren<MonoBehaviour>();
            for (int i = 0; i < mb.Length; i++)
            {
                IRevertable revertable = mb[i] as IRevertable;
                if (revertable != null)
                {
                    revertCache.AddRange(revertable.CacheState());
                }
            }

            Vector3 position = Actor.transform.localPosition;
            Quaternion rotation = Actor.transform.localRotation;
            Vector3 scale = Actor.transform.localScale;

            /*
            float frameRate = 30;
            int frameCount = (int)((Cutscene.Duration * frameRate) + 2);
            animator.StopPlayback();
            animator.recorderStartTime = 0;
            animator.StartRecording(frameCount);
            */

            base.SetRunningTime(0);
            /*
            for (int i = 0; i < frameCount-1; i++)
            {
                TimelineTrack[] tracks = GetTracks();
                for (int j = 0; j < tracks.Length; j++)
                {
                    if (!(tracks[j] is DialogueTrack))
                    {
                        tracks[j].UpdateTrack(i * (1.0f / frameRate), (1.0f / frameRate));
                    }
                }
                animator.Update(1.0f / frameRate);
            }
            animator.recorderStopTime = frameCount * (1.0f / frameRate);
            animator.StopRecording();
            animator.StartPlayback();
            */
#if UNITY_EDITOR
            UnityEditor.AnimationMode.StartAnimationMode();
#endif

            hasBeenBaked = true;

            // Return the Actor to his initial position.
            Actor.transform.localPosition = position;
            Actor.transform.localRotation = rotation;
            Actor.transform.localScale = scale;

            for (int i = 0; i < revertCache.Count; i++)
            {
                RevertInfo revertable = revertCache[i];
                if (revertable != null)
                {
                    if ((revertable.EditorRevert == RevertMode.Revert && !Application.isPlaying) ||
                        (revertable.RuntimeRevert == RevertMode.Revert && Application.isPlaying))
                    {
                        revertable.Revert();
                    }
                }
            }
            animator.cullingMode = cullingData;
            base.Initialize();
        }

        /// <summary>
        /// Cache the Actor Transform.
        /// </summary>
        /// <returns>The revert info for the Actor's transform.</returns>
        public RevertInfo[] CacheState()
        {
            RevertInfo[] reverts = new RevertInfo[3];
            if (Actor == null) return new RevertInfo[0];
            reverts[0] = new RevertInfo(this, Actor.transform, "localPosition", Actor.transform.localPosition);
            reverts[1] = new RevertInfo(this, Actor.transform, "localRotation", Actor.transform.localRotation);
            reverts[2] = new RevertInfo(this, Actor.transform, "localScale", Actor.transform.localScale);
            return reverts;
        }

        /// <summary>
        /// Initialize the Track Group as normal and initialize the Animator if in Editor Mode.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();
            if (!Application.isPlaying)
            {
                if (Actor == null) return;
                Animator animator = Actor.GetComponent<Animator>();
                if (animator == null)
                {
                    return;
                }
                //animator.StartPlayback();
            }
        }

        /// <summary>
        /// Update the Track Group over time. If in editor mode, play the baked animator data.
        /// </summary>
        /// <param name="time">The new running time.</param>
        /// <param name="deltaTime">the deltaTime since last update.</param>
        public override void UpdateTrackGroup(float time, float deltaTime)
        {
            if (Application.isPlaying)
            {
                base.UpdateTrackGroup(time, deltaTime);
            }
            else
            {
                TimelineTrack[] tracks = GetTracks();
                for (int i = 0; i < tracks.Length; i++)
                {
                    //if (!(tracks[i] is MecanimTrack))
                    {
                        tracks[i].UpdateTrack(time, deltaTime);
                    } 
                }

                /*
                if (Actor == null) return;
                Animator animator = Actor.GetComponent<Animator>();
                if (animator == null)
                {
                    return;
                }

                if (Actor.gameObject.activeInHierarchy)
                {
#if UNITY_5 && !UNITY_5_0 && !UNITY_5_1
                    if (animator.isInitialized)
                        animator.playbackTime = time;
#else
                 // if (animator.)
                        animator.playbackTime = time;
#endif


                    animator.Update(0);
                   
                }
                */
            }
        }

        public override void SetRunningTime(float time)
        {
            if (Application.isPlaying)
            {
                TimelineTrack[] tracks = GetTracks();
                for (int i = 0; i < tracks.Length; i++)
                {
                    tracks[i].SetTime(time);
                }
            }
            else
            {
                TimelineTrack[] tracks = GetTracks();
                for (int i = 0; i < tracks.Length; i++)
                {
                    //if (!(tracks[i] is MecanimTrack))
                    {
                        tracks[i].SetTime(time);
                    }
                }
                
                /*
                if (Actor == null) return;
                Animator animator = Actor.GetComponent<Animator>();
                if (animator == null)
                {
                    return;
                }
                if (Actor.gameObject.activeInHierarchy)
                {
                    animator.playbackTime = time;
                    animator.Update(0);
                }
                */
            }
        }

        /// <summary>
        /// Stop this track group and stop playback on animator.
        /// </summary>
        public override void Stop()
        {
            base.Stop();

            if (!Application.isPlaying)
            {
                if (hasBeenBaked)
                {
                    hasBeenBaked = false;
                    Animator animator = Actor.GetComponent<Animator>();
                    if (animator == null)
                    {
                        return;
                    }

                    if (animator.recorderStopTime > 0)
                    {
                        if (Actor.gameObject.activeInHierarchy)
                        {
                            /*animator.StartPlayback();
                            animator.playbackTime = 0;


                            animator.Update(0);

                            animator.StopPlayback();*/

#if UNITY_EDITOR
                            UnityEditor.AnimationMode.StopAnimationMode();
#endif
                            animator.Rebind();
                        }
                    }
                    
                }
            }
        }

        /// <summary>
        /// Option for choosing when this Event will Revert to initial state in Editor.
        /// </summary>
        public RevertMode EditorRevertMode
        {
            get { return editorRevertMode; }
            set { editorRevertMode = value; }
        }

        /// <summary>
        /// Option for choosing when this Event will Revert to initial state in Runtime.
        /// </summary>
        public RevertMode RuntimeRevertMode
        {
            get { return runtimeRevertMode; }
            set { runtimeRevertMode = value; }
        }
    }
}


2.ActorItemTrack.cs
#if UNITY_EDITOR  部分新增的

using System;
// Cinema Suite
using System.Collections.Generic;
using UnityEngine;

namespace CinemaDirector
{
    /// <summary>
    /// A track which maintains all timeline items marked for actor tracks and multi actor tracks.
    /// </summary>
    [TimelineTrackAttribute("Actor Track", new TimelineTrackGenre[] { TimelineTrackGenre.ActorTrack, TimelineTrackGenre.MultiActorTrack }, CutsceneItemGenre.ActorItem)]
    public class ActorItemTrack : TimelineTrack, IActorTrack, IMultiActorTrack
    {
        /// <summary>
        /// Initialize this Track and all the timeline items contained within.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();

            for (int i = 0; i < this.ActorEvents.Length; i++)
            {
                for (int j = 0; j < Actors.Count; j++)
                {
                    if (Actors[j] != null)
                    {
                        this.ActorEvents[i].Initialize(Actors[j].gameObject);
                    }
                }
            }
        }

        /// <summary>
        /// The cutscene has been set to an arbitrary time by the user.
        /// Processing must take place to catch up to the new time.
        /// </summary>
        /// <param name="time">The new cutscene running time</param>
        public override void SetTime(float time)
        {
            float previousTime = elapsedTime;
            base.SetTime(time);

            TimelineItem[] items = GetTimelineItems();
#if UNITY_EDITOR
            int cur_PAE_index = -1;
#endif
            for (int i = 0; i < items.Length; i++)
            {
                // Check if it is an actor event.
                CinemaActorEvent cinemaEvent = items[i] as CinemaActorEvent;
                if (cinemaEvent != null)
                {
                    if ((previousTime < cinemaEvent.Firetime && time >= cinemaEvent.Firetime) || (cinemaEvent.Firetime == 0f && previousTime <= cinemaEvent.Firetime && time > cinemaEvent.Firetime))
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                cinemaEvent.Trigger(Actors[j].gameObject);
                            }
                        }
                    }
                    else if (previousTime > cinemaEvent.Firetime && time <= cinemaEvent.Firetime)
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                                cinemaEvent.Reverse(Actors[j].gameObject);
                        }
                    }

#if UNITY_EDITOR
                    if(cinemaEvent is PlayAnimatorEvent && time >= cinemaEvent.Firetime)
                    {
                        cur_PAE_index = i;
                    }
#endif

                }

                // Check if it is an actor action.
                CinemaActorAction action = items[i] as CinemaActorAction;
                if (action != null)
                {
                    for (int j = 0; j < Actors.Count; j++)
                    {
                        if (Actors[j] != null)
                        {
                                action.SetTime(Actors[j].gameObject, (time - action.Firetime), time - previousTime);
                        }
                    }
                }
            }

#if UNITY_EDITOR
            if(cur_PAE_index >=0)
            {
                PlayAnimatorEvent playaniEvent = items[cur_PAE_index] as PlayAnimatorEvent;
                if(playaniEvent!= null)
                {
                    for (int j = 0; j < Actors.Count; j++)
                    {
                        if (Actors[j] != null)
                        {
                            playaniEvent.SamleTime(Actors[j].gameObject, (time - playaniEvent.Firetime));
                        }
                    }
                }
            }
#endif
        }

        /// <summary>
        /// Update this track since the last frame.
        /// </summary>
        /// <param name="time">The new running time.</param>
        /// <param name="deltaTime">The deltaTime since last update.</param>
        public override void UpdateTrack(float time, float deltaTime)
        {
            float previousTime = base.elapsedTime;
            base.UpdateTrack(time, deltaTime);

            TimelineItem[] items = GetTimelineItems();
#if UNITY_EDITOR
            int cur_PAE_index = -1;
#endif
            for (int i = 0; i < items.Length; i++)
            {
                // Check if it is an actor event.
                CinemaActorEvent cinemaEvent = items[i] as CinemaActorEvent;
                if (cinemaEvent != null)
                {
                    if ((previousTime < cinemaEvent.Firetime && time >= cinemaEvent.Firetime) || (cinemaEvent.Firetime == 0f && previousTime <= cinemaEvent.Firetime && time > cinemaEvent.Firetime))
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                                cinemaEvent.Trigger(Actors[j].gameObject);
                        }
                    }
                    else if (previousTime >= cinemaEvent.Firetime && base.elapsedTime <= cinemaEvent.Firetime)
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                                cinemaEvent.Reverse(Actors[j].gameObject);
                        }
                    }
#if UNITY_EDITOR
                    if (cinemaEvent is PlayAnimatorEvent && time >= cinemaEvent.Firetime)
                    {
                        cur_PAE_index = i;
                    }
#endif
                }

                CinemaActorAction action = items[i] as CinemaActorAction;
                if (action != null)
                {
                    if (((previousTime < action.Firetime || previousTime <= 0f) && base.elapsedTime >= action.Firetime) && base.elapsedTime < action.EndTime)
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                action.Trigger(Actors[j].gameObject);
                            }
                        }
                    }
                    else if (previousTime < action.EndTime && base.elapsedTime >= action.EndTime)
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                action.End(Actors[j].gameObject);
                            }
                        }
                    }
                    else if (previousTime >= action.Firetime && previousTime < action.EndTime && base.elapsedTime <= action.Firetime)
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                action.ReverseTrigger(Actors[j].gameObject);
                            }
                        }
                    }
                    else if (((previousTime > action.EndTime || previousTime >= action.Cutscene.Duration) && (base.elapsedTime > action.Firetime) && (base.elapsedTime <= action.EndTime)))
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                action.ReverseEnd(Actors[j].gameObject);
                            }
                        }
                    }
                    else if ((base.elapsedTime > action.Firetime) && (base.elapsedTime <= action.EndTime))
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                float runningTime = time - action.Firetime;
                                action.UpdateTime(Actors[j].gameObject, runningTime, deltaTime);
                            }
                        }
                    }
                }
            }

#if UNITY_EDITOR
            if (cur_PAE_index >= 0)
            {
                PlayAnimatorEvent playaniEvent = items[cur_PAE_index] as PlayAnimatorEvent;
                if (playaniEvent != null)
                {
                    for (int j = 0; j < Actors.Count; j++)
                    {
                        if (Actors[j] != null)
                        {
                            playaniEvent.SamleTime(Actors[j].gameObject, (time - playaniEvent.Firetime));
                        }
                    }
                }
            }
#endif
        }

        /// <summary>
        /// Pause playback while being played.
        /// </summary>
        public override void Pause()
        {
            base.Pause();
            TimelineItem[] items = GetTimelineItems();
            for (int i = 0; i < items.Length; i++)
            {
                CinemaActorAction action = items[i] as CinemaActorAction;
                if (action != null)
                {
                    if (((elapsedTime > action.Firetime)) && (elapsedTime < (action.Firetime + action.Duration)))
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                action.Pause(Actors[j].gameObject);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Resume playback after being paused.
        /// </summary>
        public override void Resume()
        {
            base.Resume();
            TimelineItem[] items = GetTimelineItems();
            for (int i = 0; i < items.Length; i++)
            {
                CinemaActorAction action = items[i] as CinemaActorAction;
                if (action != null)
                {
                    if (((elapsedTime > action.Firetime)) && (elapsedTime < (action.Firetime + action.Duration)))
                    {
                        for (int j = 0; j < Actors.Count; j++)
                        {
                            if (Actors[j] != null)
                            {
                                action.Resume(Actors[j].gameObject);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Stop the playback of this track.
        /// </summary>
        public override void Stop()
        {
            base.Stop();
            base.elapsedTime = 0f;
            TimelineItem[] items = GetTimelineItems();
            for (int i = 0; i < items.Length; i++)
            {
                CinemaActorEvent cinemaEvent = items[i] as CinemaActorEvent;
                if (cinemaEvent != null)
                {
                    for (int j = 0; j < Actors.Count; j++)
                    {
                        if (Actors[j] != null)
                            cinemaEvent.Stop(Actors[j].gameObject);
                    }
                }
            
                CinemaActorAction action = items[i] as CinemaActorAction;
                if (action != null)
                {
                    for (int j = 0; j < Actors.Count; j++)
                    {
                        if (Actors[j] != null)
                            action.Stop(Actors[j].gameObject);
                    }
                }
            }
        }

        /// <summary>
        /// Get the Actor associated with this track. Can return null.
        /// </summary>
        public Transform Actor
        {
            get
            {
                ActorTrackGroup atg = this.TrackGroup as ActorTrackGroup;
                if (atg == null)
                {
                    Debug.LogError("No ActorTrackGroup found on parent.", this);
                    return null;
                }
                return atg.Actor;
            }
        }

        /// <summary>
        /// Get the Actors associated with this track. Can return null.
        /// In the case of MultiActors it will return the full list.
        /// </summary>
        public List<Transform> Actors
        {
            get
            {
                ActorTrackGroup trackGroup = TrackGroup as ActorTrackGroup;
                if (trackGroup != null)
                {
                    List<Transform> actors = new List<Transform>() { };
                    actors.Add(trackGroup.Actor);
                    return actors;
                }

                MultiActorTrackGroup multiActorTrackGroup = TrackGroup as MultiActorTrackGroup;
                if (multiActorTrackGroup != null)
                {
                    return multiActorTrackGroup.Actors;
                }
                return null;
            }
        }

        public CinemaActorEvent[] ActorEvents
        {
            get
            {
                return base.GetComponentsInChildren<CinemaActorEvent>();
            }
        }

        public CinemaActorAction[] ActorActions
        {
            get
            {
                return base.GetComponentsInChildren<CinemaActorAction>();
            }
        }
    }
}


3.PlayAnimatorEvent.cs
#if UNITY_EDITOR  部分新增的

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

namespace CinemaDirector
{
    [CutsceneItemAttribute("Animator", "Play Mecanim Animation", CutsceneItemGenre.ActorItem, CutsceneItemGenre.MecanimItem)]
    public class PlayAnimatorEvent : CinemaActorEvent
    {
        public List<string>  StateName = new List<string>();
#if UNITY_EDITOR
        Dictionary<string,AnimationClip> animClips = new Dictionary<string, AnimationClip>();
#endif
        public int Layer = -1;
        public float Normalizedtime = 0.0f;
        public float speed = 1.0f;
        [SerializeField]
        private bool israndom = true;
        public bool IsRandom
        {
            get { return israndom; }
            set { israndom = value; }
        }

        public override void Trigger(GameObject actor)
        {
            Animator animator = actor.GetComponent<Animator>();
            if (animator == null)
            {
                return;
            }
            if (StateName.Count == 0)
            {
                return;
            }
            int i = Random.Range(0, StateName.Count);
            animator.speed = speed;
            if (Application.isPlaying)
            {
                if (IsRandom)
                {
                    animator.Play(StateName[i], Layer, Random.Range(0, (int)(Normalizedtime * 10)) / 10.0f);
                }
                else
                {
                    animator.Play(StateName[i], Layer, Normalizedtime);
                }
            }
        }

        public void SamleTime(GameObject actor, float time)
        {

#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                Animator animator = actor.GetComponent<Animator>();
                if (animator == null)
                {
                    return;
                }
                if (StateName.Count == 0)
                {
                    return;
                }
                int i = Random.Range(0, StateName.Count);
                animator.speed = speed;
                AnimationClip _clip = null;
                if (!animClips.ContainsKey(StateName[i]))
                {
                    AnimationClip[] tAnimationClips = animator.runtimeAnimatorController.animationClips;
                    if (tAnimationClips != null)
                    {
                        for (int j = 0; j < tAnimationClips.Length; ++j)
                        {
                            if (tAnimationClips[j] && tAnimationClips[j].name == StateName[i])
                            {
                                _clip = tAnimationClips[j];
                                animClips[StateName[i]] = _clip;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    _clip = animClips[StateName[i]];
                }
                if (_clip)   //换种方式预览角色动作
                {
                    //Debug.Log(string.Format("{0} SamleTime {1} {2} {3}", this.name, actor.name, StateName[i], time));
                    UnityEditor.AnimationMode.SampleAnimationClip(actor, _clip, time);
                }
            }
#endif
        }
    }
}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值