Unity运行时从脚本列表随机为对象添加脚本报错求助
问题排查与修复方案
错误原因分析
Random.Range参数非法
当脚本列表剩余1个元素时,scripts.Count - 1等于0,此时调用Random.Range(0, 0)会触发参数错误——int类型的Random.Range要求最大值必须大于最小值,否则会抛出异常。索引越界风险
如果初始scripts列表的元素数量不足3个,后续访问scripts[number]或执行RemoveAt操作时会直接抛出IndexOutOfRangeException。GameObject重复赋值导致空引用
你已经在Inspector面板中为User1/User2/User3赋值,但又在Start方法里用GameObject.Find重新覆盖。若场景中不存在对应名称的物体,这些变量会变为null,后续调用AddComponent时触发空引用错误。
修复后的代码
using System; using System.Collections.Generic; using UnityEngine; public class UserRandomizer : MonoBehaviour { // 在引擎面板中设置的脚本列表,请确保数量至少为3个 public List<MonoScript> scripts = new List<MonoScript>(); public GameObject User1; public GameObject User2; public GameObject User3; void Start() { // 前置校验:避免无效操作 if (scripts.Count < 3) { Debug.LogError("脚本列表元素数量不足3个,请在Inspector中补充!"); return; } if (User1 == null || User2 == null || User3 == null) { Debug.LogError("User1/User2/User3未正确赋值,请在Inspector中拖入对应GameObject!"); return; } // 复制原始列表操作,避免修改Inspector中的原始数据 var tempScripts = new List<MonoScript>(scripts); // 为User1随机分配脚本 var randomIndex = UnityEngine.Random.Range(0, tempScripts.Count); User1.AddComponent(tempScripts[randomIndex].GetType()); tempScripts.RemoveAt(randomIndex); // 为User2随机分配脚本 randomIndex = UnityEngine.Random.Range(0, tempScripts.Count); User2.AddComponent(tempScripts[randomIndex].GetType()); tempScripts.RemoveAt(randomIndex); // 为User3分配剩余的最后一个脚本 User3.AddComponent(tempScripts[0].GetType()); } }
额外注意事项
- 确保
scripts列表中添加的是继承自MonoBehaviour的可挂载脚本,不能是Editor专用脚本,否则GetType()会返回无效值。 - 直接在Inspector面板中将场景中的User1、User2、User3拖入对应变量,无需使用
GameObject.Find,避免因名称拼写错误、物体未激活导致的空引用。 - 复制临时列表进行操作,避免修改Inspector中设置的原始脚本集合,方便后续调试和复用。
内容的提问来源于stack exchange,提问作者Juan Alarcon
相关产品推荐
相关产品推荐

