Unity中GetComponentsInChildren获取子物体层级错误问题排查
问题描述
在Unity项目中,我拥有一个包含Panel的Canvas,其中包含hotbar和inventory两个独立Panel,每个Panel下都对应有slot子Panel。我尝试使用GetComponentsInChildren函数将所有slot存入数组,以修改它们的Sprite,但该函数未返回hotbar下的子物体,反而返回了hotbar面板本身。
相关代码
using UnityEngine; using UnityEngine.Tilemaps; using System; using System.Collections.Generic; public class InventoryDisplay : MonoBehaviour { public Transform[] hotbar; public Transform[] inventoryUI; [SerializeField] public Inventory inventory; public GameObject hotbarObject; public GameObject inventoryObject; void Start() { hotbar = hotbarObject.GetComponentsInChildren<Transform>(); inventoryUI = inventoryObject.GetComponentsInChildren<Transform>(); } void Update() { InventoryCheck(); } void InventoryCheck() { for (int i = 0; i < hotbar.Length; i++) { if (inventory.items[i] != Resources.Load<Item>("Items/Empty")) { hotbar[i].GetComponent<SpriteRenderer>().sprite = inventory.items[i].sprite; } else { print(hotbar[i]); hotbar[i].GetComponent<SpriteRenderer>().sprite = null; } } for (int i = hotbar.Length; i < inventoryUI.Length; i++) { if (inventory.items[i] != Resources.Load<Item>("Items/Empty")) { inventoryUI[i].GetComponent<SpriteRenderer>().sprite = inventory.items[i].sprite; } else { inventoryUI[i].GetComponent<SpriteRenderer>().sprite = null; } } } }
关键问题出在第16行,预期获取hotbarObject下的所有子物体,但实际似乎返回了主面板下的所有子物体(附Unity界面截图:Unity界面截图),请问该问题的原因是什么?
问题原因分析
GetComponentsInChildren<Transform>()默认会包含调用对象自身:所有GameObject都自带Transform组件,所以执行这个方法时,第一个返回的元素就是hotbarObject自己的Transform,这就是你看到“返回hotbar面板本身”的直接原因。- 该方法会递归获取所有层级的子物体:它不会只筛选你需要的slot子Panel,而是会把hotbarObject下所有层级的子物体的Transform都包含进来,导致数组内容和你预期的“仅slot”不符。
- UI元素误用了
SpriteRenderer组件:Unity的UI系统(比如Panel、Image)使用Image组件来显示Sprite,而SpriteRenderer是给3D物体或2D Sprite对象用的。你代码里调用GetComponent<SpriteRenderer>()根本无法获取到UI上的显示组件,后续修改Sprite的逻辑也会失效。
内容的提问来源于stack exchange,提问作者Shog
相关产品推荐
相关产品推荐

