iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
Software Development

如何在Unity裡寫出具有一定擴充性的遊戲系列 第 21

Day 21:Adapter模式與外接對話框插件

  • 分享至 

  • xImage
  •  

GoF對於轉接器模式 (Adapter)的定義是:
「將一個類別的介面轉換成為客戶端期待的類別介面。轉接器模式讓原本介面不相容的類別能一起合作」

Adapter 模式就如宇面所述,像是電器的轉接頭一樣,可以將介面轉換為符合用戶端所需要的樣貌,以便讓原本彼此不相容的類別之間(比擬為插頭與插座)可以互相配合運作。

可以使用上的時間點像是功能做到後期,架構都已經製作的差不多定型時,要是有臨時加個更改某些功能特性的功能增加,就可以使用這個設計模式。

除此之外就是這次範例的做法—外接插件,因為使用外部插件時我們時常無法確實得知他整體功能到底有甚麼地方是做的很完善、那些還有缺陷。而有些功能過多、並不是我們現階段需要的。那最好在我們自己寫的系統跟插件中間隔一層用來表示我們具體到底使用了插件的那些功能、同時也擁有可以更換其它插件的能力。

以流離之歌這款遊戲來說,我們這次使用了 Dialogue System for Unity 來做為 Adapter 的範例,在這邊最主要轉接的部分是ShowDialogueHideDialogue,這兩個 function 的功能就如名稱所說,是用來顯示與隱藏對話框的功能,至於其它什麼對話框字幕的顯示換行通通這邊不需要去處理, Dialogue System for Unity 會自己處理掉那些部分。

DialogueSystemAdapter.cs

using PixelCrushers.DialogueSystem; 
using UnityEngine; 

namespace LinXuan.TBSF.GUI.Tool 
{ 
    public class DialogueSystemAdapter : MonoBehaviour 
    { 
        [Tooltip("When open IsTest and IsDialogueComplete, can skip dialogue.")] 
        [SerializeField] private bool m_IsTest = false; 
        public bool m_IsDialogueComplete = false; 
        [SerializeField] private GameObject m_DialogueSystemTriggerGameObject; 
        [SerializeField] private DialogueSystemController dialogueSystemController; 
        [SerializeField] private SaveDataSO m_SaveDataSO; 
        private bool m_ThisSceneAlreadyTrigger = false; 

        private void Awake() 
        { 
            if (m_IsTest) 
                m_SaveDataSO.CurrentSceneDialogueIsComplete = false; 
            if (m_SaveDataSO.CurrentSceneDialogueIsComplete) 
            { 
                m_ThisSceneAlreadyTrigger = true; 
                Destroy(dialogueSystemController.gameObject); 
            } 
        }
 
        private void Update() 
        { 
            if (m_SaveDataSO.CurrentSceneDialogueIsComplete) 
                m_IsDialogueComplete = true; 
        } 

        public void ShowDialogue() 
        { 
            if (!m_IsTest && !m_ThisSceneAlreadyTrigger) 
                m_DialogueSystemTriggerGameObject.SetActive(true); 
        } 

        public void HideDialogue() 
        { 
            m_DialogueSystemTriggerGameObject.SetActive(false); 
        } 
    } 
}

如果今天是要去嘗試接其它對話功能的插件(ex:Yarn Spinner),因此要切的更乾淨的話,我會弄成下面這樣

IDialogueSystemAdapter.cs

using System; 
using UnityEngine; 

namespace LinXuan.Common.Misc.Dialogue 
{ 
    public interface IDialogueSystemAdapter 
    { 
        public void ShowDialogue(); 
        public void HideDialogue(); 
    } 

    public class DSFUDialogueSystemAdapter : MonoBehaviour, IDialogueSystemAdapter 
    { 
        public void HideDialogue() 
        { 
            //Dialogue System for Unity hide dialogue function...
        } 

        public void ShowDialogue() 
        {             
            //Dialogue System for Unity show dialogue funciton...
        } 
    } 

    public class YarnSpinnerDialogueSystemAdapter : MonoBehaviour, IDialogueSystemAdapter 
    { 
        public void HideDialogue() 
        { 
            //Yarn spinner hide dialogue function...
        } 

        public void ShowDialogue() 
        { 
            //Yarn Spinner show dialogue function...
        } 
    } 
}

這邊這樣寫的用意,與其說是去隱藏實作的細節,更像是提醒我在這個插件使用了什麼功能,而是替換其他插件時我也要做到類似的作用,不過也可能有抽象的部分太上層以至於無法完全說清楚裡面功能具體的功能運作方式,這點還是要考慮一下

參考資料

設計模式與遊戲開發的完美結合(暢銷回饋版)
Turn Based Strategy Framework
流離之歌
Dialogue System for Unity
Yarn Spinner


上一篇
Day 20:Bridge模式(二)
下一篇
Day 22:Memento模式
系列文
如何在Unity裡寫出具有一定擴充性的遊戲30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言