大家好,我是SKODE。
小提示:选中左侧目录,可快速找到所需内容
本系列博客地址:传送门
一、目标展示
利用TimeLine,实现对话框效果。
当按下空格键/(你希望的触发操作)时,继续往下进行
二、实现步骤
代码逻辑:
时间轴上代码clip决定显示的UI,决定是否运行完本clip暂停TimeLine,
那暂停后如何继续播放该TimeLine?场景中代码得到允许继续播放的输入命令时,让该TimeLine继续播放即可。
1、给某物体建立TimeLine
选中某物体,Windows-Sequencing-TimeLine,给该物体创建TimeLine属性。
2、创建 Skode_DialogueClip 脚本
该脚本需要被拖到TimeLine上,用以执行下方的 Skode_DialogueBehaviour 。
using System;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
[Serializable]
public class Skode_DialogueClip : PlayableAsset, ITimelineClipAsset
{
public Skode_DialogueBehaviour template = new Skode_DialogueBehaviour();
public ClipCaps clipCaps
{
get { return ClipCaps.None; }
}
public override Playable CreatePlayable(PlayableGraph graph, GameObject owner)
{
var playable =ScriptPlayable<Skode_DialogueBehaviour>.Create(graph, template);
return playable;
}
}
3、创建 Skode_DialogueBehaviour 脚本
该脚本被 Skode_DialogueClip 实例化执行,有自己的生命周期,执行你想要的程序。
该脚本放在Assets中即可,不用往其他地方挂。
using System;
using UnityEngine;
using UnityEngine.Playables;
[Serializable]
public class Skode_DialogueBehaviour : PlayableBehaviour
{
//播放到该clip时,UI要显示的文字
public string dialogueLine;
[Tooltip("播放完该clip后,是否需要暂停TimeLine")]
public bool hasToPause = false;
/// <summary>
/// 未播放该clip? false为未播放
/// </summary>
bool clipPlayed = false;
/// <summary>
/// 播放完该clip后是否需要暂停。false为不需要。
/// 缓存的bool变量,会在时间轴运行到该clip时,根据 hasToPause 值赋值。
/// </summary>
bool pauseScheduled = false;
/// <summary>
/// 得到当前 PlayableDirector
/// </summary>
PlayableDirector director;
public override void OnPlayableCreate(Playable playable)
{
Debug.Log("OnPlayableCreate");
director = playable.GetGraph().GetResolver() as PlayableDirector;
}
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
Debug.Log("ProcessFrame");
//若还未播放该clip,当前clip的权重>0
//效果是:时间轴刚进入该clip时执行一次
if (!clipPlayed && info.weight > 0f)
{
Debug.Log("ProcessFrame true");
Skode_GameManager.ins.SetDialogue(dialogueLine);
//检测播放完该clip后是否需要暂停,并赋值
if (Application.isPlaying && hasToPause)
{
pauseScheduled = true;
}
clipPlayed = true;
}
}
public override void OnBehaviourPause(Playable playable, FrameData info)
{
//因为该回调会在刚运行TimeLine、执行完clip时都会执行一次。
//因此不能直接判断 hasToPause ,否则刚运行TimeLine就给暂停了。
if (pauseScheduled)
{
pauseScheduled = false;
Skode_GameManager.ins.PauseTimeline(director);
}
}
}
4、创建 Skode_GameManager 脚本
该脚本内有暂停、恢复Timeline、设置UI文字的方法,并能检测输入,恢复TimeLine的执行。
该脚本挂在场景中。
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.UI;
public class Skode_GameManager : MonoBehaviour
{
public static Skode_GameManager ins;
public Text dialogueLineText;
PlayableDirector activeDirector;
private void Awake()
{
ins = this;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
ResumeTimeline();
}
}
//设置UI文字
public void SetDialogue(string lineOfDialogue)
{
dialogueLineText.text = lineOfDialogue;
dialogueLineText.gameObject.SetActive(true);
}
//暂停TimeLine
public void PauseTimeline(PlayableDirector whichOne)
{
activeDirector = whichOne;
activeDirector.Pause();
}
//恢复播放TimeLine
public void ResumeTimeline()
{
activeDirector.Resume();
}
}
现在,我们再来说一遍这三个脚本怎么用:
- Skode_DialogueClip:放在TimeLine上。
- Skode_DialogueBehaviour:放在Assets中即可。
- Skode_GameManager:挂在场景中。
一起成长,
我是SKODE。