admin管理员组文章数量:1418697
Using unity, I have a canvas with panels in it. There are two separate panels (hotbar, inventory), each with panels in it (a slot for the hotbar/inventory). I am trying to use the GetComponentsInChildren function to add all of these slots to an array, then edit their sprites from there. However, rather than getting all the children in the hotbar panel, it is returning the actual hotbar panel.
Here is the code:
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;
}
}
}
}
The important part here is line 16, where I would expect it to give all the children under the hotbarObject, but it seems to be returning all children in the main panel.
Here is a screenshot for some visual help:
Screenshot of the unity screen
Any ideas on why it's functioning like this?
Using unity, I have a canvas with panels in it. There are two separate panels (hotbar, inventory), each with panels in it (a slot for the hotbar/inventory). I am trying to use the GetComponentsInChildren function to add all of these slots to an array, then edit their sprites from there. However, rather than getting all the children in the hotbar panel, it is returning the actual hotbar panel.
Here is the code:
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;
}
}
}
}
The important part here is line 16, where I would expect it to give all the children under the hotbarObject, but it seems to be returning all children in the main panel.
Here is a screenshot for some visual help:
Screenshot of the unity screen
Any ideas on why it's functioning like this?
Share Improve this question asked Jan 29 at 13:43 ShogShog 137 bronze badges1 Answer
Reset to default 1GetComponentsInChildren
also returns components attached to the object you're running it on, not just the object's children.
From the Unity Docs for GetComponentsInChildren
:
Gets references to all components of type T on the same GameObject as the component specified, and any child of the GameObject
So there's multiple things you could do here. You can either:
Filter out the first element of each array (which would be the
Transform
of the Hotbar/InventorySlots object); either by starting the loops ati = 1
or removing the element outright through aList
.for (int i = 1; i < inventoryUI.Length; i++) { // starting from 1 skips the parent's transform ... }
Make sure to compensate for the fact that the array would be 1 item longer than there are valid slots; you would have to index based on
i - 1
, and you would have to start your second loop withi = hotbar.Length + 1
(and index withi - 2
in the inventory UI's loop).You can use the
Transform.GetChild
method (along withTransform.childCount
) on the panels' transforms to explicitly get the children.for (int i = 0; i < inventoryObject.transform.childCount; i++) { // get the transform of the children Transform x = inventoryObject.transform.GetChild(i); ... }
or, the most performant option:
Create a new component to your script that will handle populating the item's graphics (instead of having the
InventoryDisplay
do it directly for the slot), soGetComponentsInChildren
wouldn't return the parent object (sinceItemSlot
wouldn't be attached to the parent). This would also allow you to store cached references to the item slots'SpriteRenderer
s, which is ideal asGetComponent<T>
is relatively slow.public ItemSlot[] hotbar; public ItemSlot[] inventoryUI; // ... void Start() { hotbar = hotbarObject.GetComponentsInChildren<ItemSlot>(); inventoryUI = inventoryObject.GetComponentsInChildren<ItemSlot>(); } // ... void InventoryCheck() { for (int i = 0; i < hotbar.Length; i++) { int itemIndex = i; hotbar[i].UpdateGraphics(inventory.items[itemIndex]); } for (int i = 0; i < inventoryUI.Length; i++) { int itemIndex = i + hotbar.Length; inventoryUI[i].UpdateGraphics(inventory.items[itemIndex]); } }
ItemSlot.cs:
public class ItemSlot : MonoBehaviour { [SerializeField] private SpriteRenderer sRenderer; [SerializeField] private Item emptyItem; public void OnValidate() { if (!sRenderer) sRenderer = GetComponent<SpriteRenderer>(); } public void UpdateGraphics(Item item) { Sprite sprite = null; if (item && item != emptySlot) { sprite = item.sprite; } sRenderer.sprite = sprite; } }
本文标签: cWhy am I returning the wrong hierarchy level for the childrenStack Overflow
版权声明:本文标题:c# - Why am I returning the wrong hierarchy level for the children? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745294364a2651986.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论