1. 程式人生 > >利用狀態機和Trigger製作對話方塊

利用狀態機和Trigger製作對話方塊

目錄

對話方塊首先要製作好模板,包括提前設定好字型屬性和圖片位置,當然,理論上講這些是可以用程式碼進行控制的。

對話方塊的觸發

對話方塊的觸發一般有兩種方式,一種是滑鼠點選觸發,另一種是主角靠近時觸發。這兩種其實都是一種思路,利用Unity封裝好的事件機制就可以製作。

Unity還幫我們把其中滑鼠點選的事件機制封裝成UIButton,可以直接新增該Component來繫結OnButtonClick事件。但是OnTriggerEnter等這些事件還是需要自己程式碼繫結,所以我們可以把Unity中的事件機制統一做一層封裝,需要用時繼承一下就好。

下面是自己封裝好的OnTrigger2D程式碼:

using UnityEngine;
using UnityEngine.Events;

namespace Assets
{
    [RequireComponent(typeof(Collider2D))]
    public class OnTrigger2D : MonoBehaviour
    {
        public LayerMask layers;
        public UnityEvent OnEnter, OnExit;

        private void Reset()
        {
            layers = LayerMask.NameToLayer("Everything");
        }

        private void OnTriggerEnter2D(Collider2D collision)
        {
            if (!enabled)
                return;

            if (layers.Contains(collision.gameObject))
            {
                OnExcuteEnter();
            }
            
        }

        private void OnTriggerExit2D(Collider2D collision)
        {
            if (!enabled)
                return;

            if (layers.Contains(collision.gameObject))
            {
                OnExcuteExit();
            }
        }

        protected virtual void OnExcuteEnter()
        {
            OnEnter.Invoke();
        }

        protected virtual void OnExcuteExit()
        {
            OnExit.Invoke();
        }
    }
}

狀態機制作動圖

有時候對話方塊裡面的圖片要想實現簡單的動畫,可以借用狀態機來實現。這一部分涉及到AnimationClip的製作,在這裡的製作不是很複雜,有一個連結:unity製作動畫
做完之後掛在Animator上就可以實現Sprite的高速切換,避免複雜的指令碼。

指令碼自動生成對話內容

主要是使用Dict< key,value >來儲存所有的對話內容和索引。至於如何製作文字內容,這裡有兩種方式:
一種是將文字集中到.txt或.xml等檔案中,指令碼逐行或逐條讀取內容。另一種是通過SerializedProperty序列化,直接在編輯器裡編輯。從策劃的角度看,第一種雖然省事但是要比較多的程式碼量,第二種更有針對性一些。

方式一

第一種方法很簡單,主要的功夫在文字的讀取上。寫之前我羅列了要解決的幾個步驟:

  1. 匯入檔案並進行讀取
  2. 將讀取檔案存入字典中
  3. 對外提供索引

程式碼如下:

public static string[] ReadTxt(string pathName)
{
    if (pathName.Split(':').Length > 1)
    {
        return File.ReadAllLines(pathName);
        
    }
    else
    {
        string context = ((TextAsset)Resources.Load(pathName)).text;
        return context.Split('\n');
    }
}

接下來就是將讀取的文字存入Dict中:

string[] texts = ReadPhrase.ReadTxt("Phrase");
for (int i = 1; i <= texts.Length; i++)
{
    string key = "INFOPOST" + i.ToString();
    PhraseDict.Add(key, texts[i - 1]);
}

程式碼寫得隨心所欲,主要是出於學習的目的。如果要改進的話,有以下思路:

  1. .txt檔案的內容可以新增一些關鍵詞,方便切割;
  2. Dict所在的指令碼最好做成單例形式;
  3. Dict對記憶體佔用較大,如果對話內容比較多的時候不考慮用這種方式

針對第三點,第二種方式無疑是一種比較好的解決方式。

方式二

沒寫2333。。。。如果有人看到這裡,又想知道的話,私聊我補上吧。。。。。