英文:
Can't use array after it's been called from a seperate script
问题
我已经从另一个脚本中提取了一个数组,显然是打算使用它,但无法显示正确的长度。我测试了是否正确提取了它,通过引用同一脚本中的另一个变量来进行测试,那是正确的,所以我不确定为什么数组不起作用。我尝试在调用test()函数之前延迟了一秒钟,以防start()太早,数组还没有被填充,但没有成功。
是的,我已经仔细检查了所有的拼写。
public class Global {
//我试图访问的数组
public static GameObject[] BoidsArray;
//测试变量
public static int NumberOfBoids;
}
private void Awake() {
Global.BoidsArray = GameObject.Find("Main Camera").GetComponent<BoidSpawnScript>().BoidsArray;
Global.NumberOfBoids = GameObject.Find("Main Camera").GetComponent<BoidSpawnScript>().NumberOfBoids;
}
void test() {
Debug.Log(Global.BoidsArray.Length);
}
// 在第一帧更新之前调用
void Start() {
test();
}
数组和NumberOfBoids
都应该是2
,因为数组填充了这些boid,它们被生成。但是数组返回0
,而NumberOfBoids
返回2
。
编辑:
另一个填充数组的脚本部分:
BoidsArray = new GameObject[NumberOfBoids];
for (int i = 0; i < NumberOfBoids; i++) {
float randomY = Random.Range(-cHeight / 2f, cHeight / 2f);
float randomX = Random.Range(-cWidth / 2f, cWidth / 2f);
Vector2 spawnPosition = new Vector2(randomX, randomY);
GameObject newBoid = Instantiate(PhysicalBoid, spawnPosition, Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)));
BoidsArray[i] = newBoid;
}
英文:
I've pulled an Array I created in another script, obviously with the intention of using it and cannot get it to display the right length. I tested if it was pulled right by referencing another variable in the same script and that was correct, so I'm not sure why the Array won't work if that will. I tried invoking a second of delay before the test() function was called in case the start() was too early for the array to be filled, but no luck.
And yes, i've triple checked all the spelling.
public class Global {
//array I am trying to access
public static GameObject[] BoidsArray;
//test variable
public static int NumberOfBoids;
}
private void Awake() {
Global.BoidsArray = GameObject.Find("Main Camera").GetComponent<BoidSpawnScript>().BoidsArray;
Global.NumberOfBoids = GameObject.Find("Main Camera").GetComponent<BoidSpawnScript>().NumberOfBoids;
}
void test() {
Debug.Log(Global.BoidsArray.Length);
}
// Start is called before the first frame update
void Start() {
test();
}
Both the array and NumberOfBoids
should be 2
, as the array is filled with said boids as they are spawned. The array returns 0
but NumberOfBoids
gives 2
.
Edit:
the part on the other script that fills the array:
BoidsArray = new GameObject[NumberOfBoids];
for (int i = 0; i < NumberOfBoids; i++) {
float randomY = Random.Range( - cHeight / 2f, cHeight / 2f);
float randomX = Random.Range( - cWidth / 2f, cWidth / 2f);
Vector2 spawnPosition = new Vector2(randomX, randomY);
GameObject newBoid = Instantiate(PhysicalBoid, spawnPosition, Quaternion.Euler(Vector3.forward * Random.Range(0f, 360f)));
BoidsArray[i] = newBoid;
}
答案1
得分: 2
BoidsArray = new GameObject[NumberOfBoids]
创建一个新数组,并将其分配给BoidSpawnScript对象。 Global.BoidsArray
仍然持有原始数组。如果您想要访问Global脚本中的当前数组,那么您将需要添加对该脚本的引用,然后使用该引用。
在这段代码中,访问 Global.BoidsArray
总是返回来自BoidSpawnScript的当前数组。
请注意,这只是通过一种迂回的方式使BoidSpawnScript成为单例的方法,因此最好的做法可能是直接将BoidSpawnScript设为单例,而不是通过Global
脚本路由它。还要注意,使用.Find()
是不好的做法,在这种情况下,您可以直接使用 camera.main
来获取对主相机的引用。
英文:
BoidsArray = new GameObject[NumberOfBoids]
creates a new array and assigns it to the BoidSpawnScript object. Global.BoidsArray
still holds the original array. If you want to access the current array in the Global script then you'll have to add a reference to the script and use that instead.
public class Global
{
public static BoidSpawnScript BoidsScript;
public static GameObject[] BoidsArray {
get { return BoidsScript.BoidsArray; }
}
}
private void Awake() {
Global.BoidsScript = GameObject.Find("Main Camera").GetComponent<BoidSpawnScript>();
}
In this code accessing Global.BoidsArray
always returns the current array from the BoidSpawnScript.
Note that this is just a roundabout way of making the BoidSpawnScript a singleton so it might be better to just make the BoidSpawnScript a singleton instead of routing it through the Global
script. Also note that using .Find()
is bad practice and in this case you could just do camera.main
to get a reference to the main camera.
答案2
得分: 1
以下是翻译的代码部分:
为进一步解释 @GuyIncognito 的回答。
你应该使用一个类似这样的单例实例:
public class BoidSpawnScript
{
public static BoidSpawnScript instance;
public static GameObject[] BoidsArray { get; set; }
void Awake()
{
if (instance == null)
{
instance = this;
// 防止单例实例在加载新场景时被销毁
DontDestroyOnLoad(gameObject);
}
else
// 如果实例已经被赋值,销毁对象
Destroy(gameObject);
}
}
然后你可以在代码中从任何地方简单地访问静态实例,像这样:
public class MyScript
{
GameObject[] myArray;
void Start()
{
myArray = BoidSpawnScript.instance.BoidsArray;
}
}
确保不要在另一个 Awake
方法中访问该实例。你可能会尝试在它被初始化之前访问它,这将导致错误。因此,为了安全起见,请在 Start
方法或任何在 Awake
之后执行的方法中访问它。
英文:
To further @GuyIncognito's answer.
You should go for a singleton instance like this
public class BoidSpawnScript
{
public static BoidSpawnScript instance;
public static GameObject[] BoidsArray {get; set;}
OnAwake()
{
if(instance == null)
{
instance = this;
// Prevents the singleton instance being destroyed when
// loading a new scene
DontDestroyOnLoad(gameObject);
}
else
// In case the instance is already assigned
// destroys the object
Destroy(gameObject);
}
}
Then you can simply access the static instance from anywhere in your code like this
public class MyScript
{
GameObject[] myArray;
OnStart()
{
MyArray = BoidSpawnScript.instance.BoidsArray;
}
}
Be sure not to access the instance in another OnAwake
method. You might just try to access it before it is initialized and it will throw an error. So to be safe access it from an OnStart
method or any other method that executes after OnAwake
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论