You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity跨脚本调用后GameObject数组长度获取异常问题

Unity跨脚本获取数组长度异常,int变量却正常

问题情况

在Unity项目中,尝试从BoidSpawnScript脚本获取自定义的GameObject[]数组并通过Global类静态变量共享使用,但始终获取到错误的数组长度(返回0)。同时获取同脚本中的NumberOfBoids变量却能得到正确值(应为2)。尝试延迟1秒调用测试函数避免Start()执行过早,无效,且已检查所有拼写无误。

相关代码

Global类与测试脚本代码

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);
}

// Start在第一帧更新前调用
void Start() {
  test();
}

BoidSpawnScript中填充数组的代码

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;
}

原因分析

核心问题是脚本执行顺序不匹配以及引用类型的赋值时机错误:

  • NumberOfBoids是值类型(int),你在Awake()中直接赋值的是当时的数值副本,只要BoidSpawnScript在你赋值前已经将其设置为2,Global.NumberOfBoids就能拿到正确值。
  • BoidsArray是引用类型(数组),你在Awake()中获取的是BoidSpawnScript当时的数组对象引用。如果BoidSpawnScript在你获取引用之后才执行BoidsArray = new GameObject[NumberOfBoids];(重新创建数组),那么Global.BoidsArray会一直指向最初的空数组(长度0),而BoidSpawnScript中的数组已经更新为新的对象。

解决方案

方案1:调整脚本执行顺序

在Unity编辑器中进入Edit > Project Settings > Script Execution Order,将BoidSpawnScript的执行优先级调到测试脚本之前,确保它在测试脚本的Awake()执行前完成数组的初始化与填充。

方案2:动态获取数组引用

不要在Awake()中缓存数组引用,而是在需要使用时再获取最新的数组对象:

void test() {
    var spawnScript = GameObject.Find("Main Camera").GetComponent<BoidSpawnScript>();
    Global.BoidsArray = spawnScript.BoidsArray;
    Debug.Log(Global.BoidsArray.Length);
}

方案3:使用事件通知机制

在BoidSpawnScript完成数组填充后触发事件,测试脚本监听事件再获取数组,确保时机正确:

  • 在BoidSpawnScript中添加事件:
public static event Action OnBoidsSpawned;

// 填充完数组后调用此代码
OnBoidsSpawned?.Invoke();
  • 在测试脚本中监听事件:
private void OnEnable() {
    BoidSpawnScript.OnBoidsSpawned += OnBoidsReady;
}

private void OnDisable() {
    BoidSpawnScript.OnBoidsSpawned -= OnBoidsReady;
}

void OnBoidsReady() {
    Global.BoidsArray = GameObject.Find("Main Camera").GetComponent<BoidSpawnScript>().BoidsArray;
    test();
}

方案4:检查BoidSpawnScript的数组初始化时机

确保BoidSpawnScript在Awake()生命周期函数内完成数组的初始化与填充,而不是在Start()或更晚的函数中执行,避免测试脚本提前获取到未初始化的数组。


内容的提问来源于stack exchange,提问作者Lando Bunion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:36:58