c# - 如何使用对话名称作为触发器来开始对话,而不是使用索引?
问题描述
在管理器脚本中,我有一个启动对话名称的方法: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");
它将开始“开场”对话中的对话。
使用索引工作正常,但我想用对话名称开始对话会更容易。
解决方案
鉴于您正在使用 a List<T>
,如果您不再使用索引来获取所需的项目,则每次都需要枚举集合以找到相同的项目。您可以在这里做的最好的事情是将数据结构更改为 a Dictionary
,这样您就可以通过 Key 搜索它并避免性能下降。为了避免记住你在对话中输入的名字,也许最好使用枚举。
因此,创建枚举:
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 的可能值的下拉列表,因此这也更容易处理。
推荐阅读
- machine-learning - Kubeflow 是否有助于以分布式方式运行 ML
- python - 如何在 Python 中检查文件中使用的 shell 命令
- python - __del__ 函数中的 open() 导致 LookupError
- android - 我正在尝试统一构建我的 android 游戏,但他们向我展示了一个问题“无法合并 android 清单”
- python - 将 python 项目部署到 PYPI 时隐藏 API 密钥
- reactjs - 如何在 Highcharts 的图表中呈现具有 x 和 y 值的对象数组“webdata”?
- php - 如何在不替换旧文本的情况下将文本添加到文本区域
- java - 错误程序类型已存在:程序类型已存在:添加新库时的 androidx.recyclerview.widget.AdapterHelper$Callback
- excel - 用文本和图像从 Excel 填充 Word 文档,图像部分需要帮助
- azure - AKS 上的身份服务器