我的对话系统遇到了问题。
我有一个脚本“对话管理器”,它带有一个“对话框”脚本,用于输入/输出用户。当玩家靠近npc并按下空格键时,每个npc都会有自己的对话持有者传递给对话管理器。
在dialogManager中,我像这样引用对话框脚本:
public dialogueHolder dh;
在dialogHolder脚本中我有这段代码将dialogHolder初始化为dialogManager:
dManager.dialogueHolder = this;
这在使用基本的dialogHolder脚本时工作正常,但它只是单个npcs对话的模板。我怎样才能创建多个对话持有者,我可以在dialogManager中以相同的方式引用它?例如,我有一个脚本dialogHolder_yellowMage,它有一个关于mage npc的特定对话,我如何将它引用到DialogueManager中的dh变量?因为dialogHolder_yellowMage与dialogHolder有不同的标题,所以我不能这样引用它。
我试图改变
public dialogueHolder dh;
到
public Object dh;
但是我不能引用dialogHolder脚本中的任何变量。
对于文本墙感到抱歉,我是stackOverflow和C#的新手。请帮助新手!
答案 0 :(得分:2)
看起来你正在做这样的事情:
public class dialogueHolder_yellowMage {
public string MessageToSay;
}
public class dialogueHolder_redMage {
public string MessageToSay;
}
public class dialogueHolder_blueMan {
public string MessageToSay;
}
..
// public dialogueHolder_? dh;
public object dh; // Only this would work, but it's not what you want!
首先要注意的是,他们都在重复相同的事情(或者至少重复相同的概念)。相反,不是每个NPC有一个独特的类,而是有一个代表对话的类:
public class DialogueHolder {
// The message they'll say
public string MessageToSay;
}
...
// Then we *instance* one for each of our NPCs:
DialogueHolder yellowMage = new DialogueHolder();
yellowMage.MessageToSay = "I'm feeling great!";
DialogueHolder redMage = new DialogueHolder();
redMage.MessageToSay = "I'm so angry!";
..
在这种情况下,他们都使用相同类的实例。这意味着您现在可以执行public DialogueHolder dh;
并且该功能正常。
如果一个类描述了一个概念,那么继承就是描述相关概念。例如,狗是一种动物。法师是一种NPC。但是对话通常没有这些独特的类别,所以继承可能不是你想要使用的。
当您使用Unity时,我们可以将这些实例转换为美观且可视化的内容 - 在检查器中使用组件。组件脚本如下所示:
// DialogueHolder.cs
using UnityEngine;
using System.Collections;
public class DialogueHolder : MonoBehaviour { // (This is also inheritance)
// The message they'll say
public string MessageToSay;
}
常见误解的时间: Unity默认使用创建组件脚本。这通常会让人们认为所有类必须继承MonoBehaviour,这不是Unity的工作方式。只有在某些东西真正用作组件时才会继承MonoBehaviour。
在编辑器中单击您的一个NPC,然后查看检查器;你会看到一个“添加组件”按钮。单击它,然后您将获得脚本选项:
在那里,您可以选择DialogueHolder
课程。一旦你添加了它,你就会在检查器中看到这种东西:
Unity已将该类作为NPC游戏对象的一个组件实例化
这非常有用;然后,您可以单独编辑Message To Say
。您的班级中的大多数public
字段在检查器中都是可见的(并且可编辑),因此您可以添加一堆其他对话相关字段:
// DialogueHolder.cs
using UnityEngine;
using System.Collections;
public class DialogueHolder : MonoBehaviour {
// The message they'll say
public string MessageToSay;
// Some kind of 2D chat head image
public Texture2D ChatHead;
// etc!
}
因此,假设您的播放器在场景中走动,并且位于某个gameObject的聊天范围内。您可以使用tagging快速检查gameObject x
是否是NPC。在场景启动时,按finding all GameObjects that are tagged as an NPC存储所有可用NPC的列表,然后循环检查玩家距离每个NPC的距离。当玩家在其中一个范围内时,您可以像这样抓住DialogueHolder:
// Try getting the dialogue holder:
DialogueHolder dh = aGameObject.GetComponent<DialogueHolder>();
if (dh == null) {
// This NPC doesn't feel like talking (you didn't give it a DialogueHolder)
} else {
// Do something with dh
}
一个功能齐全的对话系统当然超出了这个范围,但无论如何这都是基础知识!