无法在从不同脚本调用后使用数组。

huangapple go评论56阅读模式
英文:

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(&quot;Main Camera&quot;).GetComponent&lt;BoidSpawnScript&gt;().BoidsArray;
  Global.NumberOfBoids = GameObject.Find(&quot;Main Camera&quot;).GetComponent&lt;BoidSpawnScript&gt;().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 &lt; 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(&quot;Main Camera&quot;).GetComponent&lt;BoidSpawnScript&gt;();
}

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.

huangapple
  • 本文由 发表于 2023年5月25日 13:33:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76329192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定