如何让AI识别数组中所有GameObject?Unity遍历生成球报错求解
问题原因与修复方案
报错根本原因
- 遍历语法错误:
foreach循环中取出的变量本身就是targetBall数组中的GameObject实例,不是数组下标,无需再用targetBall[变量]的方式取值,直接用遍历变量即可访问当前轮次的球对象。 - 变量名大小写不匹配:C#为大小写敏感语言,你的数组命名为
targetBall,但foreach中写的是targetball(首字母B小写),也会触发变量未找到的错误。 - 潜在逻辑冲突:如果直接遍历所有球控制AI移动,当多个符合条件的球同时存在时,移动指令会互相覆盖,导致AI移动抖动、逻辑异常,建议优先选择距离最近、朝向AI飞行的球作为当前处理目标。
修正后的代码
void Move() { targetBall = GameObject.FindGameObjectsWithTag("HokeyBall"); // 优先筛选朝向AI飞的最近的球,避免多球指令冲突 GameObject currentTarget = null; float minDistance = float.MaxValue; foreach (GameObject ball in targetBall) { HokyBall ballScript = ball.GetComponent<HokyBall>(); // 只处理朝向AI飞行的球 if (ballScript.ballDirection == Vector3.right) { float distance = Vector3.Distance(transform.localPosition, ball.transform.localPosition); if (distance < minDistance) { minDistance = distance; currentTarget = ball; } } } // 找到合法目标再执行移动逻辑 if (currentTarget != null) { Vector3 ballPos = currentTarget.transform.localPosition; if (transform.localPosition.x < Lboundry && ballPos.x > transform.localPosition.x) { transform.localPosition += new Vector3(speed * Time.deltaTime, 0, 0); } if (transform.localPosition.x < Lboundry && ballPos.x < transform.localPosition.x) { transform.localPosition += new Vector3(-speed * Time.deltaTime, 0, 0); } } }
额外优化建议
- 不要每次调用
Move都执行FindGameObjectsWithTag,这个API性能开销较大,建议你生成球的时候直接往全局的List<GameObject>里添加,球销毁的时候从列表里移除,遍历列表比每次查找标签效率高得多,也完美支持无限生成球的需求。 - 可以增加距离阈值判断,只处理在AI前方一定范围内的球,避免远处的球干扰AI当前的判断。
内容的提问来源于stack exchange,提问作者Yasir
相关产品推荐
相关产品推荐

