- Home /
How do I access an instantiated Image.sprite inside a GameObject inside a for-loop?
Hi everyone,
I hope someone can help me, I searched online for answers but I never found an answer, this is what I need: I have a FOR loop in which I instantiate a prefab I have prepared, inside that FOR loop I also change the .text value of the "Name" Text object, sort of like this:
champPrefab.GetComponentInChildren<Text>().text = champName;
Where "champPrefab" is the prefab Object i created and "champName" is the value I want to give to the Text object. I would love to change the .sprite of an image inside that same loop of an Image object inside the prefab, but I don't know how to access it, or at least
champPrefab.GetcomponentInChilden<Image>()
doesen't do the job.
For clarity I'll leave an image of the prefab and its hierarchy I'm trying to access the highlighted object inside the for-loop I don't know if it helps but the other objects inside the Prefab are:
Prefab
Image
Image <= the one I want to access the .sprite of
Image
Text
Button
public class StatsUpdate : MonoBehaviour
{
public GameObject PrefabChampIcon;
public Transform ChampSelectParent;
void Start()
{
foreach (var champ in champList) //"champ" is an item inside a List of local paths
{
GameObject champPrefab = Instantiate(PrefabChampIcon, transform.position, transform.rotation);
champPrefab.transform.SetParent(ChampSelectParent);
champPrefab.GetComponentInChildren<Text>().text = champName;
StartCoroutine(GetImage(champPrefab.GetcomponentInChilden<Image>(), localPatVar));
}
}
IEnumerator GetImage(Image _img, string _path)
{
UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(_path);
yield return uwr.SendWebRequest();
if (uwr.isHttpError || uwr.isNetworkError)
{
Debug.Log(uwr.error);
}
else
{
Texture2D imgTexture2d = ((DownloadHandlerTexture)uwr.downloadHandler).texture;
_img.sprite = Sprite.Create(imgTexture2d, new Rect(0,0,120,120), Vector2.zero);
}
}
}
Thanks in advance :P
Answer by jackmw94 · Nov 10, 2020 at 11:08 PM
I think you're going down the wrong path with the web requests; these are used when you want to get some resource from a website or at some URL path!
The only thing blocking your from getting the Image the same way as you do the Text component is that there are multiple, meaning that if you only get one it's likely just going to give you the first one it finds. I think you have two options here: if this will be the last time you have to sort through multiple components then it's find to just use the GetComponentsInChildren function to return all the Images in the hierarchy, then search through them to find the one you want:
private Image GetChampImage(GameObject champObject)
{
var allImages = champObject.GetComponentsInChildren<Image>();
foreach (Image img in allImages)
{
if (img.gameObject.name.Equals("ChampImage"))
{
return img;
}
}
Debug.LogError("Could not find champ image!");
return null;
}
Then inside your foreach-loop you can just call:
Image champImg = GetChampImage(champ);
champImg.sprite = ... // whatever you want to set the sprite to
However if you want to be a little more organised with this you can have a container for all these references that will sit on the root (champSelectFace) object. After you've added this, remember to drag the correct references in inside the prefab:
public class ChampSelectFaceElements : MonoBehaviour
{
public Text ChampNameText;
public Image ChampImage;
}
So instead of then getting the text or searching for the image, you can instead just get the ChampSelectFaceElements and access the references via this! Inside your foreach-loop you can do this via:
var champRefs = champFace.GetComponent<ChampSelectFaceElements>();
champRefs.ChampText.text = champName;
champRefs.ChampImage.sprite = // sprite!
Thank You so so much for your answer, I took every option into consideration and deceided to go for the last one, I agree it is the best idea. This tought me a valuable lesson: planning goes a long way. In this case goes as far as to make the approach I had almost the worst idea possible. Will remember this for future scripting.
Ah I wouldn't say worst idea, there's a 'path' to the gameobject so I see where you were co$$anonymous$$g from. Everyone's gotta start somewhere, hope you're enjoying it!
On a side note I would be interested in knowing how you would go about getting images from a local file, searching the web i found many obsolete methods (www) and in the end I just went with "what worked". Should probably point out that I'm kid of new to unity (2 weeks into it) so if the questions are newbie-like that's because I'm still getting used to c# and how unity itself operates. (having a blast with unity / c# by the way ;) )
Your answer
Follow this Question
Related Questions
Change a prefab sprite using Random.range instantiate in a script 3 Answers
How to make a gameObject instantiate a prefab for every 250 damage taken ? 4 Answers
How to check if a component is on an instantiated prefab? 1 Answer
Lobbing a Bomb with Instantiate. 1 Answer
How can I instantiate multiple objects with a loop and have them be different 1 Answer