gameObject 的多个实例表现不尽相同
Multiple instances of gameObject not performing identically
所以我的游戏世界中有三个不同的 'bystanders',每个都有一个附加的 'Bystander' 脚本,并且我的 UI 有一个 'BystanderDialogue' 元素。这个想法是,当玩家进入任何旁观者的范围时,会显示从数据库中随机选择的文本,但对于我的脚本,它只对其中一个旁观者有效。
我觉得我交叉引用脚本太多了之类的,但我不知道。下面是两段代码:
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> ();
}
}
如果有多个旁观者对象,那么您只保留最后一个对象作为对 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
实例
所以我的游戏世界中有三个不同的 'bystanders',每个都有一个附加的 'Bystander' 脚本,并且我的 UI 有一个 'BystanderDialogue' 元素。这个想法是,当玩家进入任何旁观者的范围时,会显示从数据库中随机选择的文本,但对于我的脚本,它只对其中一个旁观者有效。
我觉得我交叉引用脚本太多了之类的,但我不知道。下面是两段代码:
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> ();
}
}
如果有多个旁观者对象,那么您只保留最后一个对象作为对 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
实例