Как я могу использовать имя разговора в качестве триггера, чтобы начать разговор вместо использования индекса? - PullRequest
0 голосов
/ 13 апреля 2019

Внутри скрипта менеджера у меня есть метод, который запускает имя диалога: StartDialogue:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class DialogueManager : MonoBehaviour
{
    public Text dialogueText;
    public Text nameText;
    public float sentencesSwitchDuration;
    public bool animateSentenceChars = false;
    public GameObject canvas;
    public static bool dialogueEnded = false;
    public DialogueTrigger trigger;

    private Queue<string> sentence;

    // Use this for initialization
    void Start()
    {
        sentence = new Queue<string>();
    }

    public void StartDialogue(Dialogue dialogue)
    {
        canvas.SetActive(true);

        nameText.text = dialogue.name;

        sentence.Clear();
        foreach (string sentence in dialogue.sentences)
        {
            this.sentence.Enqueue(sentence);
        }

        DisplayNextSentence();
    }

    public void DisplayNextSentence()
    {
        if (this.sentence.Count == 0)
        {
            EndDialogue();
            return;
        }

        string sentence = this.sentence.Dequeue();
        dialogueText.text = sentence;

        StopAllCoroutines();
        StartCoroutine(DisplayNextSentenceWithDelay(sentence));
    }

    public IEnumerator DisplayNextSentenceWithDelay(string sentence)
    {
        if (animateSentenceChars)
        {
            dialogueText.text = "";
            foreach (char letter in sentence.ToCharArray())
            {
                dialogueText.text += letter;
                yield return null;
            }
        }

        yield return new WaitForSeconds(sentencesSwitchDuration);
        DisplayNextSentence();
    }

    private void EndDialogue()
    {
        dialogueEnded = true;
        if (trigger.dialogueNum == trigger.conversations[trigger.dialogueIndex].Dialogues.Count)
            canvas.SetActive(false);
        Debug.Log("End of conversation.");
    }
}

Затем в скрипте триггера у меня есть имя метода TriggerDialogue, которое получает номер индекса. Например, индекс 0 запустит дозвоны первого разговора. Но на самом деле это только начало первого диалога из списка диалогов.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

[ExecuteInEditMode]
public class DialogueTrigger : MonoBehaviour
{
    public List<Conversation> conversations = new List<Conversation>();
    //public List<Dialogue> dialogue = new List<Dialogue>();

    [HideInInspector]
    public int dialogueNum = 0;

    [HideInInspector]
    public int dialogueIndex = 0;

    private bool triggered = false;
    private List<Dialogue> oldDialogue;
    private bool activateButton = false;

    public void TriggerDialogue(int dialogueIndex)
    {
        this.dialogueIndex = dialogueIndex;

        if (conversations.Count > 0 &&
            conversations[dialogueIndex].Dialogues.Count > 0)
        {
            if (triggered == false)
            {
                if (FindObjectOfType<DialogueManager>() != null)
                {
                    FindObjectOfType<DialogueManager>().StartDialogue(conversations[dialogueIndex].Dialogues[dialogueNum]);
                    dialogueNum += 1;
                }
                triggered = true;
            }
        }
    }

    private void Update()
    {
        ButtonActivation();

        if (DialogueManager.dialogueEnded == true)
        {
            if (dialogueNum == conversations[dialogueIndex].Dialogues.Count)
            {
                return;
            }
            else
            {
                FindObjectOfType<DialogueManager>().StartDialogue(conversations[dialogueIndex].Dialogues[dialogueNum]);
                DialogueManager.dialogueEnded = false;
                dialogueNum += 1;
            }
        }
    }

    public bool ActivateButton()
    {
        return activateButton;
    }

    private void ButtonActivation()
    {
        if (ConversationsChecks() == true)
        {
            foreach (string sentence in conversations[dialogueIndex].Dialogues[dialogueNum].sentences)
            {
                if (sentence != "")
                {
                    activateButton = true;
                }
                else
                {
                    activateButton = false;
                }
            }
        }
        else
        {
            activateButton = false;
        }
    }

    public void SaveConversations()
    {
        string jsonTransform = JsonHelper.ToJson(conversations.ToArray(), true);
        File.WriteAllText(@"d:\json.txt", jsonTransform);
    }

    public void LoadConversations()
    {
        string jsonTransform = File.ReadAllText(@"d:\json.txt");
        conversations.Clear();
        conversations.AddRange(JsonHelper.FromJson<Conversation>(jsonTransform));
    }

    private bool ConversationsChecks()
    {
        bool IsConversationsReady = false;

        if (conversations.Count > 0 &&
            conversations[dialogueIndex].Dialogues.Count > 0 &&
            conversations[dialogueIndex].Dialogues[dialogueNum].sentences.Count > 0 &&
            conversations[dialogueIndex].Dialogues[dialogueNum].name != "" &&
            conversations[dialogueIndex].name != "")
        {
            IsConversationsReady = true;
        }
        else
        {
            IsConversationsReady = false;
        }

        return IsConversationsReady;
    }
}

Тогда у меня есть еще два маленьких класса:

Диалог:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Dialogue
{
    [Tooltip("Dialogue Name")]
    public string name;

    [TextArea(1, 10)]
    public List<string> sentences = new List<string>();
}

И разговор:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Conversation
{
    [Tooltip("Conversation Name")]
    public string name;

    public List<Dialogue> Dialogues = new List<Dialogue>();
}

Так что теперь, когда я хочу начать диалог, я вызываю метод TriggerDialogue, как в этом примере:

dialogueTrigger.TriggerDialogue(0);

Вместо этого я хочу сделать что-то подобное:

dialogueTrigger.StartConversation("Opening Scene");

или

dialogueTrigger.StartConversation("The last conversation");

А вот пример экрана, на котором выглядит инспектор диалогов и диалогов:

Диалоги

Так, если, например, я хочу начать первый разговор где-нибудь в моей игре, я сделаю:

dialogueTrigger.StartConversation("The Opening");

И он запустит диалоги внутри разговора «Открытие».

Использование индекса работает нормально, но я хочу использовать, чтобы начать разговор по имени разговора, это будет проще.

1 Ответ

0 голосов
/ 13 апреля 2019

Учитывая, что вы используете List<T>, если вы отойдете от использования индекса для получения нужного элемента, вам нужно будет каждый раз перечислять коллекцию, чтобы найти этот же элемент. Лучшее, что вы можете здесь сделать, это изменить структуру данных на Dictionary, чтобы вы могли искать ее по ключу и избежать снижения производительности. Чтобы также не помнить, какие имена вы называете в разговорах, возможно, было бы лучше использовать Enum.

Итак, создайте перечисление:

public enum SceneConversations
{
    OpeningScene = 1,
    // ...
}

и начните использовать

public class DialogueTrigger : MonoBehaviour
{
    public Dictionary<SceneConversations, Conversation> conversations = new Dictionary<SceneConversations, Conversation>();

затем вы можете использовать

public void StartConversation(SceneConversations conversationWanted) {}

и позвоните по номеру

dialogueTrigger.StartConversation(SceneConversations.OpeningScene);

Если я правильно помню, это дает дополнительное преимущество: Unity покажет вам раскрывающийся список возможных значений SceneConversations, так что с ним также легче работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...