c# - gameObject 的多个实例表现不尽相同

标签 c# unity3d gameobject

所以我的游戏世界中有三个不同的“旁观者”,每个都有一个附加的“旁观者”脚本,并且我的 UI 中有一个“旁观者对话”元素。这个想法是,当玩家进入任何旁观者的范围时,会显示从数据库中随机选择的文本,但对于我的脚本,它只对其中一个旁观者有效。

我觉得我交叉引用脚本太多了,但我不知道。下面是两部分代码:

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

public class Bystander : MonoBehaviour {

GameObject player;
public bool speak;
public bool isPlayerNear;
public int dialogueNumber;
GameObject bystanderDialogueObject;
BystanderDialogue bystanderDialogue;


// Use this for initialization
void Awake () 
{
    player = GameObject.FindGameObjectWithTag ("Player");
    bystanderDialogueObject = GameObject.Find ("BystanderDialogue");
    bystanderDialogue = bystanderDialogueObject.GetComponent<BystanderDialogue> ();
}

// Update is called once per frame
void Update () 
{

}

void OnTriggerEnter(Collider other)
{
    if (other.gameObject == player) 
    {
        dialogueNumber = Random.Range (0, bystanderDialogue.bystanderSpeech.Length);
        speak = true;
        isPlayerNear = true;
    }
}

void OnTriggerExit(Collider other)
{
    if (other.gameObject == player) 
    {
        speak = false;
        isPlayerNear = false;
    }
}
}

第二个附加到 UI 对象“BystanderDialogue”:

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

public class BystanderDialogue : MonoBehaviour {

Text text;
GameObject[] bystanderObjects;
Bystander bystander;
public string[] bystanderSpeech;
// Use this for initialization
void Awake () 
{
    text = GetComponent<Text> ();
    bystanderObjects = GameObject.FindGameObjectsWithTag ("NPC");
    foreach (GameObject bystanderObject in bystanderObjects) 
    {
        bystander = bystanderObject.GetComponent<Bystander> ();
    }
}

// Update is called once per frame
void Update () 
{
        BystanderSpeak (bystander);

        if (bystander.isPlayerNear) 
        {
            Debug.Log ("New bystander!");
        }

}

void BystanderSpeak(Bystander bystander)
{
    if (bystander.speak && bystander.isPlayerNear) 
    {
        text.text = bystanderSpeech[bystander.dialogueNumber];
    }
    else if (!bystander.speak && !bystander.isPlayerNear)
    {
        text.text = "";
    }
}
}

我很确定我犯了一些基本错误,所以很抱歉。非常感谢任何帮助!

最佳答案

这段代码没有意义:

void Awake () 
{
    text = GetComponent<Text> ();
    bystanderObjects = GameObject.FindGameObjectsWithTag ("NPC");
    foreach (GameObject bystanderObject in bystanderObjects) 
    {
        bystander = bystanderObject.GetComponent<Bystander> ();
    }
}

如果有多个 bystanderObject,那么您只保留最后一个对象作为 bystander 成员字段的引用。您应该使用集合(列表或数组)来保留所有这些:

Bystander[] bystanders;


void Awake()
{
    bystanderObjects = GameObject.FindGameObjectsWithTag ("NPC");
    bystanders = new Bystander[bystanderObjects.Length];
    for (var i = 0; i < bystanderObjects.Length; ++i)
    {
        bystander[i] = bystanderObjects[i].GetComponent<Bystander>();
    }
}

编辑:您似乎误解了 Unity 中两帧之间的一切运作方式。我建议你阅读 Execution Order of Event Functions .

您的 Update() 方法将在屏幕上绘制任何内容之前完成。因此,如果您覆盖 Text 的值,则只会显示最后写入的值。事实上,每个 bystander 都需要一个 Text 实例。

关于c# - gameObject 的多个实例表现不尽相同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30630338/

相关文章:

c# - 列出所有 session 信息

c# - 将 WebImage 上传到 FTP

c# - 将字典或列表转换为 byte[]

algorithm - 如何在 Unity 中对齐 "tracks"或模块化对象?

c# - 如何更新 Unity GameObject 以沿样条曲线移动?

unity3d - 将 Unity 可编写脚本的对象附加到 GameObject

c# - 如何在 C# 中通过 shell 执行文件?

c# - 在另一个进程内调用不是用 .NET 编写的函数

c++ - 如何从四面体网格中提取表面三角形?

unity-game-engine - 统一无限生成游戏对象