unity劇情繫統開發

從去年三月份到現在,《匣》斷斷續續的也經歷一年多的開發,這幾天劇情繫統也算是穩定下來了,後面應該不會再進行大概了,一開始還搞了個節點編輯器,結果後來整個劇情跳轉邏輯改了,編輯器也沒用了。後面有時間還是想把編輯器搞起來,否則配表真的是太麻煩了。

簡介

  《匣》是一款劇情向的2d遊戲,所有整個劇情繫統是基於文字內容的,並不需要什麼人物的行爲。基於這一點,整個劇情繫統主體分爲下面三部分

  • StoryManager
  • StoryData/StoryHandler
  • TriggerData/TriggerHandler

StoryManager

  這個管理器並不直接管理劇情,它既不存儲劇情數據,也不定義某個劇情的表現形式。當你傳了一個劇情數據或者是觸發器數據給它時,它會根據數據類型選擇對應的Handler再具體去做某件事。系統的核心部分是沒有對數據進行管理的,所以數據怎麼存儲可以由外界定義。

StoryHandler

  按照我們的設計需要,劇情被分爲了普通,CG,顧客等幾種,每種劇情都有着自己的表現方式。所有就有個了StoryHandler(劇情處理器)的概念。每種類型的劇情都對應一個處理器。處理器核心代碼只有一個接口和一個泛型基類。泛型基類的方法只有OnHandleStory是其派生類必須實現的,並且要定義好劇情處理完成的時機去調用callback。其他方法一般不用重寫。

public interface IStoryHandler
{
    /// <summary>
    /// 對應的故事類型
    /// </summary>
    Type StoryDataType { get; }
    /// <summary>
    /// 處理劇情數據
    /// </summary>
    /// <param name="storyDataBase">劇情</param>
    /// <param name="callback">完成後的回調</param>
    void Handle(StoryDataBase storyDataBase, Action callback = null);
}

public abstract class StoryHandlerBase<T> : IStoryHandler where T : StoryDataBase
{
    public Type StoryDataType => typeof(T);
	/// <summary>
	/// 處理劇情數據
	/// </summary>
	/// <param name="storyDataBase">劇情</param>
	/// <param name="callback">完成後的回調</param>
    public void Handle(StoryDataBase storyDataBase, Action callback = null)

    /// <summary>
    /// 開始故事前檢查是否滿足觸發條件
    /// </summary>
    /// <param name="storyData"></param>
    /// <returns></returns>
    protected virtual bool OnCheckStory(T storyData)

    /// <summary>
    /// 處理故事
    /// </summary>
    /// <param name="storyData"></param>
    /// <param name="callback">故事結束後的回調</param>
    protected abstract void OnHandleStory(T storyData, Action callback);

    /// <summary>
    /// 故事結束後處理一些事情,比如後續劇情
    /// </summary>
    /// <param name="storyData"></param>
    protected virtual void OnStoryEnd(T storyData)
}

TriggerHandler

  一個劇情結束後,可能會觸發其他劇情,但觸發方式不一樣,有的可能會立即觸發,有的可能會隔幾天,等等。這樣一來,就需要多種觸發器來定義一個劇情被觸發的方式。
  觸發器的核心代碼和劇情處理器基本一致,並且更簡單一些,也是一個接口和一個泛型基類。
  在匣開發過程中,並不是每一種觸發器數據都對應一個處理器。有些觸發器可能會在別的地方處理。這一點是同劇情處理器不一樣(如果某種類型的劇情沒有定義對應的處理器,該數據在傳給StoryManager後會拋出一個異常)

/// <summary>
/// 故事觸發處理器
/// </summary>
public interface ITriggerHandler
{
    Type TriggerDataType { get; }
    void Handle(ITriggerData triggerData);
}

/// <summary>
/// 故事觸發數據的處理器基類
/// </summary>
/// <typeparam name="T">觸發器類型</typeparam>
public abstract class StoryTriggerHandlerBase<T> : ITriggerHandler where T : ITriggerData
{
    public Type TriggerDataType => typeof(T);
    public void Handle(ITriggerData triggerData)
    protected abstract void HandleTriggerData(T triggerData);
}

總結

  有了這些基礎代碼之後,再對應去實現所需要的劇情表現形式,可以實現一個相對比較豐富的文字劇情繫統。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章