改善原因
而有一些對話,設計者可能會希望玩家不用按任何按鍵,只要走到能對話的位置,就會自動觸發對話,可能藉此讓玩家之到一些他必須要知道的事情。
Unity實作
Dialogue
在Dialogue腳本宣告一個bool型別的變數,用來決定此Dialogue是不是一個要直接觸發的對話。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
[System.Serializable]
public class Dialogue
{
public string dialogueName;
public bool isCompelete = false;
public bool directTrigger = false;
public List<Condition> taskConditions;
[Space(15)]
public List<Sentence> sentences;
public UnityEvent finishEvent;
public void InvokeFinishEvent()
{
finishEvent.Invoke();
}
}
TalkBehav
在TalkBehav腳本裡,當取得Dialogue後,判斷是不是要直接觸發的對話,如果是的話就開始對話。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TalkBehav : MonoBehaviour
{
private RoleObj roleObj;
private DialoguesManager dialoguesManager;
private SpriteRenderer spR;
private void Start()
{
roleObj = GetComponent<RoleObj>();
dialoguesManager = FindObjectOfType<DialoguesManager>();
spR = GetComponent<SpriteRenderer>();
}
private void Update()
{
InvokeDialogue();
FaceTheSpeakerInDialogue();
}
/// <summary>
///啟動對話
/// </summary>
private void InvokeDialogue()
{
if (isInDialogueTrigger && dialoguesManager.IsDialogueCompelete)
{
dialoguesManager.GetDialogue();
if (Input.GetKeyDown(KeyCode.Space) || dialoguesManager.Dialogue.directTrigger)//判斷對話是不是直接觸發的
{
dialoguesManager.StartDialogue();
}
}
}
/// <summary>
///讓角色面對在對話的人
/// </summary>
private void FaceTheSpeakerInDialogue()
{
if (dialoguesManager.IsDialogueCompelete == false)
{
Vector3 speakerPosition = dialoguesManager.DialogueRolesCenterPosition;
if (speakerPosition.x > transform.position.x)
{
spR.flipX = false;
}
else if (speakerPosition.x < transform.position.x)
{
spR.flipX = true;
}
}
}
private bool isInDialogueTrigger = false;
//當進入到勾選Trigger的Collider的瞬間會執行的方法
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.layer == LayerMask.NameToLayer("Area"))
//如果碰到的 勾選Trigger的Collider的物件 Layer是Area
{
AreaNumKeeper.currentNum = other.GetComponent<Area>().num;
Debug.Log(AreaNumKeeper.currentNum);
}
else if (other.gameObject.layer == LayerMask.NameToLayer("DialogueTrigger"))
{
isInDialogueTrigger = true;
ShowTheHint();
}
}
/// <summary>
///顯示提示訊息
/// </summary>
public void ShowTheHint()
{
roleObj.BubbleScaleUp("...");
}
//當離開勾選Trigger的Collider的瞬間會執行的方法
private void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.layer == LayerMask.NameToLayer("Area"))
{
if (AreaNumKeeper.currentNum == other.GetComponent<Area>().num)
{
AreaNumKeeper.currentNum = -1;
Debug.Log(AreaNumKeeper.currentNum);
}
}
else if (other.gameObject.layer == LayerMask.NameToLayer("DialogueTrigger"))
{
isInDialogueTrigger = false;
roleObj.BubbleScaleDown();
}
}
}
結論
到這裡,這次的對話系統教學文章就告一段落了。
希望這篇文章能讓正在閱讀的你,了解如何使用Unity實作對話系統。
有問題、有興趣交流或想繼續學習的人,可以在本篇或每篇文章的留言區留言~
系列文章
《Carto》實作對話系統01-前言
《Carto》實作對話系統02-建立遊戲所需物件
《Carto》實作對話系統03-建構程式
《Carto》實作對話系統04-把腳本加到對應的物件上
《Carto》實作對話系統05-當TextMeshPro沒有辦法顯示中文
《Carto》實作對話系統06-改善對話系統的操作介面
《Carto》實作對話系統07-加入對話結束後會觸發的事件
參考文獻
- Unity – Scripting API: MonoBehaviour.OnTriggerEnter2D(Collider2D) (unity3d.com)
- Is using a yield return null a hack implemented by Unity. – Unity Forum
- Unity – Scripting API: MonoBehaviour.StartCoroutine (unity3d.com)
- Unity – Manual: Coroutines (unity3d.com)
- Events.UnityEvent – Unity 脚本 API (unity3d.com)
- DOTween (HOTween v2) | Animation Tools | Unity Asset Store
- Font Asset Properties | TextMeshPro | 4.0.0-pre.1 (unity3d.com)
- Unity – Scripting API: UnityEvent<T0,T1,T2,T3> (unity3d.com)
- Naming array elements in editor – Unity Answers
- Unity – Manual: 9-slicing Sprites (unity3d.com)
- Unity – Scripting API: MonoBehaviour.OnDrawGizmos() (unity3d.com)
- Unity UI – How is Image preferred size determined? – Unity Forum
- Unity – Manual: Conditional Compilation (unity3d.com)
- Unity – Manual: Important Classes – Gizmos & Handles (unity3d.com)
- Unity – Scripting API: Handles (unity3d.com)
- Unity – Scripting API: Handles.Label (unity3d.com)
- Unity – Scripting API: GUIStyle (unity3d.com)
- 教育部4808個常用字說明.pdf (moe.gov.tw)
- Noto Sans Traditional Chinese – Google Fonts
- Canvas | Unity UI | 1.0.0 (unity3d.com)
- Unity UGUI 原理篇(五):Auto Layout 自動佈局 | ARKAI Studio
- Unity UGUI 原理篇(一):Canvas 渲染模式 | ARKAI Studio
- Unity – Scripting API: Serializable (unity3d.com)
- Unity – Scripting API: TextAreaAttribute (unity3d.com)
- Unity – Scripting API: GameObject.GetComponent (unity3d.com)
- Unity – Scripting API: Input.GetAxisRaw (unity3d.com)
- Unity – Scripting API: MinAttribute (unity3d.com)
- Unity – Scripting API: MonoBehaviour.OnValidate() (unity3d.com)
- Unity – Scripting API: SpaceAttribute (unity3d.com)
- Minimum value in public variables? – Unity Answers
- Unity UI – How is Image preferred size determined? – Unity Forum
- Unity UI – How is Image preferred size determined? – Unity Forum
- Font Asset Creator | TextMeshPro | 4.0.0-pre.1 (unity3d.com)
- Content Size Fitter | Unity UI | 1.0.0 (unity3d.com)
- TextMesh Pro ForceMeshUpdate(true) not working when object inactive – Unity Forum
- how to draw debug text into scene? – Unity Answers
- Unity – Manual: Important Classes – Gizmos & Handles (unity3d.com)