对话系统本身就是一个非常广泛的话题。但是,我认为您无法仅使用字符串列表来完成它。如果您正在谈论让玩家有选择权,那么您将需要创建一些自定义类。
首先,您需要一个类来定义角色的选项。这将是一个非常简单的类。它将包含字符串响应和一个表示目标节点的整数。
public class DialogueOption {
public string Text;
public int DestinationNodeID;
}
接下来,您将需要一个 DialogueNode 类。考虑一下 NPC 告诉角色的内容,然后它还包含一个列表,您猜对了,对话选项。它将拥有的另一件事是 NodeID。这是一个整数,它为我们提供了一个从我们的选项发送我们到的地方。它看起来有点像这样:
public class DialogueNode {
public int NodeID = -1; //I use -1 as a way to exit a conversation.
//NodeId should be a positive number
public string Text;
public List<DialogueOption> Options;
}
最后,您需要创建 Dialogue 类,它是所有类中最简单的,只是一个 DialogueNode 列表,看起来像这样:
public class Dialogue {
public List<DialogueNode> Nodes = new List<DialogueNode>();
}
你可以在你的角色只有一个对话脚本的情况下使用它,但是我的做法不同,每个角色都有另一个名为 DialogueList 的类,它基本上是一个对话列表,它还包含我可以显示的角色名称和根据情况,我可以选择我希望我的角色当时与玩家进行的对话。
public class DialogueList
{
public string name;
public List<Dialogue> dialogues = new List<Dialogue>();
}
这还有一个额外的好处,即如果您想在那个方向上设置它,可以使用名称作为返回对话列表的键轻松转换为字典。
在您项目的其他地方,您将需要一个 DialogueManager 类来控制一切。我通常将其设为 Singleton,以便我可以从任何地方轻松调用它。我不会向您展示所有内容,但我会向您展示显示部分,其余的只是设置文本以及打开和关闭对象。
public void RunDialogue(string name, Dialogue dia)
{
nameText.text = name;
StartCoroutine(run(dia));
}
IEnumerator run(Dialogue dia)
{
DialoguePanel.SetActive(true);
//start the convo
int node_id = 0;
//if the node is equal to -1 end the conversation
while (node_id != -1 )
{
//display the current node
DisplayNode(dia.Nodes[node_id]);
//reset the selected option
selected_option = -2;
//wait here until a selection is made by button click
while (selected_option == -2)
{
yield return new WaitForSeconds(0.25f);
}
//get the new id since it has changed
node_id = selected_option;
}
//the user exited the conversation
EndDialogue(node_id);
}
我的按钮基本上只是在我在 DisplayNode 方法下设置的 OnClick 事件中附加了这个简单的方法。基本上,我拿着我的按钮给他们这个方法,他们的参数是他们的DialogueOption.DestinationId是什么
public void SetSelectedOption(int x)
{
selected_option = x;
}