基于TimeLine编辑角色动画(二)

如何在Clip范围内执行相应的操作

有两种方法:

官方的方法(一)、通过playable.GetInputWeight(i),获得Weight,在播放到Clip范围内如果没有过渡的话Weight=1,如果没有Clip范围内,Weight=0;

并在ProcessFrame 每帧判断Weight。

 

(二)、PlayableBehaviour 有两个重载方法

OnBehaviourPlay()在Clip开始播放到范围时执行,OnBehaviourPause()在离开Clip播放范围时执行

可以设置个bool变量控制。

 

 

如果需要混合的动画最终的逻辑写在MixerBehaviour 的ProcessFrame(),否则写在Playabehavior的OnBehaviourPlay()。在Playabehavior中想拿到外部引用,可以在PlayableClip中 ExposedReference<>,在外部绑定。

 

 

 

自动绑定代码 

 

    [Button("重新绑定")]
    void BuilderPlayableDirector()
    {
        if (playableDirector==null)
        playableDirector = GetComponent<PlayableDirector>();
        if(animator==null)
        animator = GetComponent<Animator>();
        if(playerController==null)
        playerController = GetComponent<PlayerController>();
        if(audioSource==null)
        audioSource = Camera.main.GetComponent<AudioSource>();
        if (playableAssets.Values.Count==0)
        {
            LoadPlayableAssets(PlayerCareer.Warrior);
        }
        foreach (var pa in playableAssets.Values)
        {
            TimelineAsset timeline = pa as TimelineAsset;
            foreach (TrackAsset item in timeline.GetOutputTracks())
            {
                BindTrack(item);
                BindClip(item);
            }
        }
    }

 

    void BindClip(TrackAsset item)
    {
        foreach (TimelineClip i in item.GetClips())
        {
           object clipAsset= i.asset;
            if (clipAsset is CameraShakeTrackClip)
            {
                CameraShakeTrackClip p = clipAsset as CameraShakeTrackClip;
                playableDirector.SetReferenceValue(p.playerController.exposedName, playerController);
            }
        }

    }
    void BindTrack(TrackAsset item)
    {
        IEnumerable<PlayableBinding> bind = item.outputs;
        foreach (PlayableBinding b in bind)
        {
            if (b.outputTargetType != null)
            {
                switch (b.outputTargetType.Name)
                {
                    case "Animator":
                        playableDirector.SetGenericBinding(b.sourceObject, animator);
                        break;
                    case "AudioSource":
                        playableDirector.SetGenericBinding(b.sourceObject, audioSource);
                        break;
                    case "PlayerController":
                        playableDirector.SetGenericBinding(b.sourceObject, playerController);
                        break;
                    default:
                        break;
                }
            }

        }
    }

另外说一个测试结果 当Animator和PlayableDirector同时存在时,只播放PlayableDirector,可以将角色的Idle,Run,Walk等没有太多动画事件的动画使用Animator播放,需要大量编辑的复杂动画使用PlayableDirector播放。

posted @ 2021-01-22 14:40  wsfw  阅读(420)  评论(0编辑  收藏  举报