Timeline脚本事件运用及常用接口使用

目录

一、脚本事件运用

代码部分:

运行结果:

二、常用接口使用


一、脚本事件运用

Add添加Playable Track轨道,在后面的轨道中右键会有Event System Playable文本显示,点击创建。

代码部分:

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

//Timeline脚本事件运用
public class EventSystemPlayable : PlayableAsset
{
    public string eventId;
    public string param;

    public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
    {
        var playable = ScriptPlayable<NewPlayableBehaviour>.Create(graph);
        playable.GetBehaviour().eventId = eventId;
        playable.GetBehaviour().param = param;
        return playable;
    }
}

public class NewPlayableBehaviour : PlayableBehaviour
{
    public string eventId;
    public string param;
   
    public override void OnBehaviourPlay(Playable playable, FrameData info)
    {
        Debug.Log("发送事件 id :"+ eventId+ "___param :"+ param);
        //EventMgr.Instance.SendEvent(eventId, param);
    }

    public override void PrepareFrame(Playable playable, FrameData info)
    {
        Debug.Log("触发时每帧都执行");
    }
}


运行结果:

二、常用接口使用

using System;
using UnityEngine;
using UnityEngine.Timeline;
using UnityEngine.Playables;
using Cinemachine.Timeline;
using Cinemachine;

public static class TimelineHelper
{
    #region ModifyTrack 修改一个Track
    /// <summary>
    /// 修改一个Track
    /// </summary>
    /// <param name="director">PlayableDirector</param>
    /// <param name="trackName">通道名称</param>
    /// <param name="value">要附着的物体</param>
    public static void ModifyTrack(PlayableDirector director, string trackName, GameObject value, bool addAnimator)
    {
        try
        {
            foreach (PlayableBinding item in director.playableAsset.outputs)
            {
                if (item.streamName == trackName)
                {
                    if (addAnimator)
                    {
                        Animator animator = value.GetComponent<Animator>();
                        if (animator == null)
                        {
                            animator = value.AddComponent<Animator>();
                        }
                        animator.cullingMode = AnimatorCullingMode.AlwaysAnimate;

                        SkinnedMeshRenderer[] smr = value.GetComponentsInChildren<SkinnedMeshRenderer>();
                        if (smr != null)
                        {
                            for (int i = 0; i < smr.Length; i++)
                            {
                                smr[i].updateWhenOffscreen = true;
                            }
                        }
                    }
                    director.SetGenericBinding(item.sourceObject, value);
                    break;
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
        }
    }
    #endregion

    #region ModifyAudioClip 修改一个ModifyAudioClip
    /// <summary>
    /// 修改一个ModifyAudioClip
    /// </summary>
    /// <param name="director">PlayableDirector</param>
    /// <param name="trackIndex">通道索引</param>
    /// <param name="clipName">片段名称</param>
    /// <param name="value">要附着的物体</param>
    public static void ModifyAudioClip(PlayableDirector director, int trackIndex, string clipName, AudioClip audioClip)
    {
        TimelineAsset tl = director.playableAsset as TimelineAsset;
        TrackAsset track = tl.GetOutputTrack(trackIndex);
        foreach (var item in track.GetClips())
        {
            AudioPlayableAsset audioAsset = item.asset as AudioPlayableAsset;
            if (clipName == item.displayName)
            {
                audioAsset.clip = audioClip;
                break;
            }
        }
    }
    #endregion

    #region ModifyControlClip 修改一个ControlClip
    /// <summary>
    /// 修改一个ControlClip
    /// </summary>
    /// <param name="director">PlayableDirector</param>
    /// <param name="trackIndex">通道索引</param>
    /// <param name="clipName">片段名称</param>
    /// <param name="value">要附着的物体</param>
    public static void ModifyControlClip(PlayableDirector director,int trackIndex, int clipIndex, GameObject value)
    {
        if (value == null || director == null)
        {
            Debug.LogWarning("TimelineHelper.ModifyControlClip  value == null || director == null  return!!");
            return;
        }
        try
        {
            if (!director.playableGraph.IsValid())
            {
                director.RebuildGraph();
            }
            TimelineAsset tl = director.playableAsset as TimelineAsset;
            TrackAsset track = tl.GetOutputTrack(trackIndex);
            int index = 0;
            foreach (var item in track.GetClips())
            {
                if (index == clipIndex)
                {
                    ControlPlayableAsset asset = item.asset as ControlPlayableAsset;
                    director.playableGraph.GetResolver().SetReferenceValue(asset.sourceGameObject.exposedName, value);
                    break;
                }
                ++index;
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
        }
    }
    #endregion

    public static void ModifyAnimationClip(PlayableDirector director, int trackIndex, int clipIndex, AnimationClip value)
    {
        if (value == null || director == null)
        {
            Debug.LogWarning("TimelineHelper.ModifyAnimationClip  value == null || director == null  return!!");
            return;
        }
        try
        {
            if (!director.playableGraph.IsValid())
            {
                director.RebuildGraph();
            }
            TimelineAsset tl = director.playableAsset as TimelineAsset;
            TrackAsset track = tl.GetOutputTrack(trackIndex);
            int index = 0;
            foreach (var item in track.GetClips())
            {
                if (index == clipIndex)
                {
                    AnimationPlayableAsset asset = item.asset as AnimationPlayableAsset;
                    asset.clip = value;
                    break;
                }
                ++index;
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
        }
    }
 
    public static void SetClipRootMotionOffset(PlayableDirector director, int trackIndex, int clipIndex, CinemachineVirtualCamera vcam)
    {
        if (vcam == null || director == null)
        {
            return;
        }
        try
        {
            TimelineAsset tl = director.playableAsset as TimelineAsset;
            TrackAsset track = tl.GetOutputTrack(trackIndex);
            int index = 0;
            foreach (var item in track.GetClips())
            {
                if (index == clipIndex)
                {
                    AnimationPlayableAsset clip = item.asset as AnimationPlayableAsset;
                    //Debug.Log("vcam " + vcam.name);
                    CinemachineTransposer transposer = (CinemachineTransposer)vcam.GetCinemachineComponent(CinemachineCore.Stage.Body);
                    if (transposer)
                    {
                        clip.position = transposer.m_FollowOffset;
                    }
                    clip.rotation = vcam.transform.rotation;
                    break;
                }
                ++index;
            }
        }
        catch (Exception e)
        {
            Debug.LogError (e.ToString());
        }
    }

    #region ModifyCinemachineClip 修改一个ModifyCinemachineClip
    /// <summary>
    /// 修改一个ModifyCinemachineClip
    /// </summary>
    /// <param name="director">PlayableDirector</param>
    /// <param name="trackIndex">通道索引</param>
    /// <param name="clipName">片段名称</param>
    /// <param name="value">要附着的物体</param>
    public static void ModifyCinemachineClip(PlayableDirector director, int trackIndex, int clipIndex, GameObject vcamGo)
    {
        if (vcamGo == null || director == null)
        {
            return;
        }
        CinemachineVirtualCameraBase vcam = vcamGo.GetComponent<CinemachineVirtualCameraBase>();
        if (vcam == null)
        {
            return;
        }
        try
        {
            if (!director.playableGraph.IsValid())
            {
                director.RebuildGraph();
            }
            TimelineAsset tl = director.playableAsset as TimelineAsset;
            //Debug.Log("trackIndex " + trackIndex);
            //Debug.Log("clipIndex " + clipIndex.ToString());
            TrackAsset track = tl.GetOutputTrack(trackIndex);
            int index = 0;
            foreach (var item in track.GetClips())
            {
                if (index == clipIndex)
                {
                    CinemachineShot shot = item.asset as CinemachineShot;
                    director.playableGraph.GetResolver().SetReferenceValue(shot.VirtualCamera.exposedName, vcam);
                    break;
                }
                ++index;
            }
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
        }
    }
    #endregion
    public static string GetTimeStamp()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
        return Convert.ToInt64(ts.TotalSeconds).ToString() + UnityEngine.Random.Range(0, 100);
    }

    public static void ReguildGraph(PlayableDirector director)
    {
        if (!director.playableGraph.IsValid())
        {
            director.RebuildGraph();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/m1234567q/article/details/114339974