如何在脚本A中单独访问脚本B,C,D?

时间:2017-01-05 07:27:58

标签: c# unity3d

我的对话系统遇到了问题。

我有一个脚本“对话管理器”,它带有一个“对话框”脚本,用于输入/输出用户。当玩家靠近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#的新手。请帮助新手!

1 个答案:

答案 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组件

当您使用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,然后查看检查器;你会看到一个“添加组件”按钮。单击它,然后您将获得脚本选项:

Adding a script in Unity Indie

在那里,您可以选择DialogueHolder课程。一旦你添加了它,你就会在检查器中看到这种东西:

Instance of a script

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获取DialogueHolder

因此,假设您的播放器在场景中走动,并且位于某个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

}

一个功能齐全的对话系统当然超出了这个范围,但无论如何这都是基础知识!