項目 divider 尚未註冊或是沒有一個 view.php 檔案.

《Carto》實作對話系統08-當條件滿足時,不用按按鍵,可以直接觸發的對話

改善原因

而有一些對話,設計者可能會希望玩家不用按任何按鍵,只要走到能對話的位置,就會自動觸發對話,可能藉此讓玩家之到一些他必須要知道的事情。

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-加入對話結束後會觸發的事件

參考文獻

  1. Unity – Scripting API: MonoBehaviour.OnTriggerEnter2D(Collider2D) (unity3d.com)
  2. Is using a yield return null a hack implemented by Unity. – Unity Forum
  3. Unity – Scripting API: MonoBehaviour.StartCoroutine (unity3d.com)
  4. Unity – Manual: Coroutines (unity3d.com)
  5. Events.UnityEvent – Unity 脚本 API (unity3d.com)
  6. DOTween (HOTween v2) | Animation Tools | Unity Asset Store
  7. Font Asset Properties | TextMeshPro | 4.0.0-pre.1 (unity3d.com)
  8. Unity – Scripting API: UnityEvent<T0,T1,T2,T3> (unity3d.com)
  9. Naming array elements in editor – Unity Answers
  10. Unity – Manual: 9-slicing Sprites (unity3d.com)
  11. Unity – Scripting API: MonoBehaviour.OnDrawGizmos() (unity3d.com)
  12. Unity UI – How is Image preferred size determined? – Unity Forum
  13. Unity – Manual: Conditional Compilation (unity3d.com)
  14. Unity – Manual: Important Classes – Gizmos & Handles (unity3d.com)
  15. Unity – Scripting API: Handles (unity3d.com)
  16. Unity – Scripting API: Handles.Label (unity3d.com)
  17. Unity – Scripting API: GUIStyle (unity3d.com)
  18. 教育部4808個常用字說明.pdf (moe.gov.tw)
  19. Noto Sans Traditional Chinese – Google Fonts
  20. Canvas | Unity UI | 1.0.0 (unity3d.com)
  21. Unity UGUI 原理篇(五):Auto Layout 自動佈局 | ARKAI Studio
  22. Unity UGUI 原理篇(一):Canvas 渲染模式 | ARKAI Studio
  23. Unity – Scripting API: Serializable (unity3d.com)
  24. Unity – Scripting API: TextAreaAttribute (unity3d.com)
  25. Unity – Scripting API: GameObject.GetComponent (unity3d.com)
  26. Unity – Scripting API: Input.GetAxisRaw (unity3d.com)
  27. Unity – Scripting API: MinAttribute (unity3d.com)
  28. Unity – Scripting API: MonoBehaviour.OnValidate() (unity3d.com)
  29. Unity – Scripting API: SpaceAttribute (unity3d.com)
  30. Minimum value in public variables? – Unity Answers
  31. Unity UI – How is Image preferred size determined? – Unity Forum
  32. Unity UI – How is Image preferred size determined? – Unity Forum
  33. Font Asset Creator | TextMeshPro | 4.0.0-pre.1 (unity3d.com)
  34. Content Size Fitter | Unity UI | 1.0.0 (unity3d.com)
  35. TextMesh Pro ForceMeshUpdate(true) not working when object inactive – Unity Forum
  36. how to draw debug text into scene? – Unity Answers
  37. Unity – Manual: Important Classes – Gizmos & Handles (unity3d.com)
Colin TPL
Colin TPL

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *