Unity中MonoBehaviour的Start()执行异常:数组长度先0后1引发索引越界问题咨询
Unity中MonoBehaviour的Start()执行异常:数组长度先0后1引发索引越界问题咨询
看起来你遇到了Unity生命周期和脚本实例管理的典型问题,我来帮你拆解一下:
问题根源分析
为什么Length会打印两次?
你看到的日志其实来自两个不同的Hacking脚本实例:- 第一个实例的
buttons数组没有在Inspector中赋值,所以buttons.Length是0,访问buttons[0]直接触发索引越界异常。 - 第二个实例的
buttons数组已经正确赋值,所以能正常打印长度、循环遍历按钮并输出按钮信息。
日志顺序看起来混乱,是因为异常抛出后,第二个实例的日志紧接着输出了(Unity的日志输出不一定严格按执行顺序排列,尤其是有异常的时候)。另外你提到的“UnrealEngine”应该是手滑打错啦,咱们用的是UnityEngine 😄
- 第一个实例的
为什么会出现空数组的实例?
大概率是场景中存在多个挂载了Hacking脚本的对象:- 你可能只给其中一个对象的
buttons数组在Inspector面板中赋值了,另一个/几个对象的buttons数组是空的。 - 也有可能是你在代码中通过
AddComponent<Hacking>()动态添加了脚本实例,但没有给这些动态创建的实例赋值buttons数组。
- 你可能只给其中一个对象的
解决步骤
第一步:排查多余的脚本实例
- 在Unity编辑器顶部的搜索框中输入
Hacking,查看场景中所有挂载了该脚本的对象。 - 删除不需要的脚本实例,或者给每个实例的
buttons数组都正确赋值(把对应的Button拖到Inspector的数组列表里)。
第二步:添加安全校验避免异常
不管有没有多实例,在访问数组前添加校验都是好习惯,能避免不必要的异常:
void Start() { print("Start"); // 先校验数组是否有效 if (buttons == null || buttons.Length == 0) { Debug.LogWarning("Buttons数组未赋值或为空,请在Inspector中配置!", this); return; } print("Length: " + buttons.Length); // 添加点击事件 foreach (Button button in buttons) { print("Loop"); print("Button: " + button); // 这里可以添加button.onClick.AddListener(...)的逻辑 } print(buttons[0]); }
第三步:纠正MonoBehaviour的初始化习惯
注意:Unity不推荐给MonoBehaviour写自定义构造函数!因为MonoBehaviour的对象是由Unity引擎负责创建和管理的,构造函数的执行时机完全不可控,很容易导致初始化异常。你应该通过Inspector赋值public变量,或者用[SerializeField]标记私有变量来在Inspector中配置,再在Awake或Start中做初始化逻辑。
备注:内容来源于stack exchange,提问作者Xaver
相关产品推荐
相关产品推荐

