2017-02-04 9 views
1

私は単純なツリーベースの対話システムに取り組んでいます。ストーリーを進めるためにクリックの基本的なゲーム、選択するための別の選択肢、別のストーリーのパスに主役のプレーヤー。効率的なツリーベースの対話システム?

私がしたことは、Convoというゲームオブジェクトの過多を作成することでした。各ConvoにはText(Component)とChildrenがあり、どのキャラクターが画面上にあるかを判別し、その子供の中のタグを使ってその旋律を表示します(悲しい喜びなど)。 例

  • A-0-1(テキスト: "ジョン:?ねえ、何が起こっている")(タグと "選択" それが最後の会話の場合)タグと
    • ジョン(「アイドルイライラ "「タグ付き)
    • ジェーン(")

Story path picture

CurrentDialogue(string)とDialogueTracking(int)の2つの変数があります。

クリックごとに、現在のconvoにタグ "Choice"があるかどうかを確認します。存在しない場合は、CurrentDialogue(文字列)を使用して、正確な名前のgameobjectを見つけてテキストを表示します。 DialogueTrackingを1つ増やし、

そして、DialogueTrackingを使用してCurrentDialogue(文字列)をA-0-1からA-0-2に変更しました。また、タグ "choice"(例A-0-4 )、DialogueTracking(int)は1にリセットされるので、プレイヤーが選択肢を選択した後、A-1-5の代わりにA-1-1です。

ここに問題があります。多くのコンボと多くのストーリーパスの後、私は初心者の間違いを認識します。コードが大きく変わった場合(どの選択がどのパスになるかを比較)

私はプログラミングと統合には全く新しいです。どのようにこのシステムをクリーンで効率的なものにするために、それは本当に素晴らしいでしょう!

ありがとうございました!

+0

多分インターフェースを使用して、それを構造化? https://unity3d.com/learn/tutorials/topics/scripting/interfaces – Absinthe

答えて

1

あなたのすべてのダイアログを保持し、それぞれが他のダイアログを参照する必要があります。DialogueManagerComponentをお勧めします。ダイアログを表示した後、複数の子供がいるかどうかをチェックしたり、子供が1人いる(または誰もいない)ことを確認したり、ダイアログのポップアップを表示したりできます。

それはようになるコードの例では:今、あなたのUnityインスペクタ内にこれを記入してくださいあなたのDialogue Sを管理するためにDialogueManagerComponentをしなければならない

[Serializable] 
public class Dialogue 
{ 
    [SerializeField] 
    Dictionary<string, Dialogue> _dialogues; 

    [SerializeField] 
    string _dialogueText; 

    public Dialogue(string text) 
    { 
     _dialogues = new Dictionary<string, Dialogue>(); 
     _dialogueText = text; 
    } 

    public string GetText() { return _dialogueText; }  

    public bool HasManyPaths() { return _dialogues.Count > 1; } 

    public string[] GetKeys() { return _dialogues.Keys; } 

    public Dialogue GetDialogue(string key) { return _dialogues[key]; } 
} 

することができます。このメソッドを使用して
public class DialogueManager 
    : Component 
{ 
    [SerializeField] 
    Dialogue _currentDialogue; 

    public void InitializeDialogue() 
    { 
     string text = _currentDialogue.GetText(); 
     // display the text 
     if (_currentDialogue.HasManyPaths()) 
     { 
      string[] keys = _currentDialogue.GetKeys(); 
      // display keys; 
      string selected_key = // user input here 
      _currentDialogue = _currentDialogue.GetDialogue(selected_key); 
     } 
     else 
     { 
      string key = _currentDialogue.GetKeys()[0]; 
      _currentDialogue = _currentDialogue.GetDialogue(key); 
     } 
    } 
} 

Unityエディタ内で対話を行い、MonoBehaviourスクリプトに次のような文字列を追加してください:

対話ツリーを作る
public void Start() 
{ 
    GetComponent<DialogueManager>().InitializeDialogue(); 
} 

簡単な例は次のようになります。

{ currentDialogue [ "hello! choose 1 or 2" ] 
    1.{ dialogue [ "you've chosen 1" ] 
     . { dialogue [ "this ends dialogue" ] } 
    } 
    2. { dialogue [ "you've chosen 2" ] 
     . { dialogue [ "now choose another number between 3 and 4" ] 
      3. { dialogue [ "you've chosen 3" ] } 
      4. { dialogue [ "you've chosen 4" ] } 
     } 
    } 
} 
+0

返信いただきありがとうございます!私がシリアライゼーションについて学んでいるのはこれが初めてであるので、私はコードのいくつかのラインしか理解していません。私が理解しているところでは、以前のText(コンポーネント)はダイアログのツリー全体を格納するためにDialogue(スクリプト)に置き換えられますか? Dialogue(スクリプト)から_currentDialogueを取得してテキストを表示し、正しい選択肢があれば別のパスに移動するための入力を受け取るのはDialogueManager(スクリプト)です。私はそれがすべて間違っているように感じる、あなたはもっと私を明確にすることができますか?ありがとう! – Irfx

+0

@Irfxあなたはそれを正しく理解しています。シングは、カスタムインスペクタを作成する必要があると思いますが、それが必要であるかどうかはわかりません。 :)いくつかのデイルが必要な場合はコメントしてください。スクリーンショットを作成し、この回答を編集してより明確にするようにします。 –

関連する問題