Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Difficulties changing Image sprite from SpriteRenderer sprite

Discussion in 'Scripting' started by Naiveca, Feb 20, 2023.

  1. Naiveca

    Naiveca

    Joined:
    Apr 14, 2019
    Posts:
    34
    I'm trying to change the Image of an UI image with the one from the GameObject.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UIElements;
    5.  
    6. public class BuildingUI : MonoBehaviour
    7. {
    8.     [SerializeField] private List<GameObject> parts;
    9.     public GameObject slotPrefab;
    10.     private Sprite slotImage;
    11.  
    12.     private void Start()
    13.     {
    14.         foreach (var part in parts)
    15.         {
    16.             slotImage = part.GetComponent<SpriteRenderer>().sprite;
    17.             Instantiate(slotPrefab, transform);
    18.             slotPrefab.transform.GetChild(0).GetComponent<Image>().sprite = slotImage;
    19.         }
    20.     }
    21. }
    22.  
    The image sprite won't change and I'm getting this error

    Code (CSharp):
    1. ArgumentException: GetComponent requires that the requested component 'Image' derives from MonoBehaviour or Component or is an interface.
    I can't figure it out :/

    Can <Image>().sprite and <SpriteRenderer>().sprite be used together or what's the difference anyway?
     
  2. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    This error message is indicating that the Image component that you are trying to get from slotPrefab.transform.GetChild(0) is not derived from MonoBehaviour or Component, or is not an interface.

    The Image component in Unity is derived from the UIBehaviour class, which is derived from MonoBehaviour. So it should be okay to get the Image component with GetComponent<Image>().

    However, it looks like you are trying to get the Image component from a child object of slotPrefab. It's possible that the child object doesn't have an Image component, which is causing the error.

    To fix the issue, you can add an Image component to the child object, or you can make sure that the child object has an Image component before trying to get it.

    Like this:
    Code (CSharp):
    1. private void Start()
    2. {
    3.     foreach (var part in parts)
    4.     {
    5.         slotImage = part.GetComponent<SpriteRenderer>().sprite;
    6.         GameObject slot = Instantiate(slotPrefab, transform);
    7.         Image image = slot.transform.GetChild(0).GetComponent<Image>();
    8.         if (image != null)
    9.         {
    10.             image.sprite = slotImage;
    11.         }
    12.         else
    13.         {
    14.             Debug.LogError("Child object of slotPrefab does not have an Image component.");
    15.         }
    16.     }
    17. }
    18.  
    This code first gets the child object of slotPrefab, and then checks if it has an Image component using GetComponent<Image>(). If the child object doesn't have an Image component, it logs an error message to the console. Otherwise, it sets the sprite property of the Image component to slotImage.
     
  3. Naiveca

    Naiveca

    Joined:
    Apr 14, 2019
    Posts:
    34
    The child of slotPrefab is a default UI Image added through the menu, that's pretty much the only component it has. It's null by default, does this matter?
     
  4. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    As long as there's an image attached, I don't think so. Let me know if the above code works and then we'll work from there.
     
  5. Naiveca

    Naiveca

    Joined:
    Apr 14, 2019
    Posts:
    34
    Throws the same error, image won't change. If I add a random default sprite to the slotImage it won't change anything, as it doesn't matter if it's null or not?
     
  6. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    What are you trying to do exactly?
     
  7. Naiveca

    Naiveca

    Joined:
    Apr 14, 2019
    Posts:
    34
    In part in parts is an GameObject. It has a <SpriteRenderer> component, it has a sprite obviously.
    I instantiate an UI element (Panel) that has a child that's an Image.
    I'm trying to get the sprite from the GameObject to display as the image of the child object (Image) of the UI element (Panel).

    I'll add that if I manually change the Image sprite to the one of the GameObject it works like I would want it to.
     
  8. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UIElements;
    5. using UnityEngine.UI;
    6. public class BuildingUI : MonoBehaviour
    7. {
    8.     [SerializeField] private List<GameObject> parts;
    9.     public GameObject slotPrefab;
    10.     private void Start()
    11.     {
    12.         foreach (var part in parts)
    13.         {
    14.             Sprite slotImage = part.GetComponent<SpriteRenderer>().sprite;
    15.             GameObject slot = Instantiate(slotPrefab, transform);
    16.             Image image = slot.transform.GetChild(0).GetComponent<Image>();
    17.             if (image != null)
    18.             {
    19.                 image.sprite = slotImage;
    20.             }
    21.             else
    22.             {
    23.                 Debug.LogError("Child object of slotPrefab does not have an Image component attached.");
    24.             }
    25.         }
    26.     }
    27. }
    28.  
     
  9. Naiveca

    Naiveca

    Joined:
    Apr 14, 2019
    Posts:
    34
    This part of the code ain't coding.

    Added this and it works, but it seems kinda odd.
    using Image = UnityEngine.UI.Image;
     
  10. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    Are you using UIElements? I don't think so and even Unity's official docs recommend against it yet.

    Remove the using if you're not.

    Everything I see above is UnityEngine.UI namespace.
     
  11. Naiveca

    Naiveca

    Joined:
    Apr 14, 2019
    Posts:
    34
    Thanks, fixed the issue without using this monstrosity.
    Code (CSharp):
    1. using Image = UnityEngine.UI.Image;
     
  12. Leuki

    Leuki

    Joined:
    Feb 27, 2014
    Posts:
    130
    I only left that in there cause he had it. Wasn't sure if he needed it for another reason. I did however add
    using UnityEngine.UI;
    since he left it out in his original script.
     
  13. Naiveca

    Naiveca

    Joined:
    Apr 14, 2019
    Posts:
    34
    Yeah, thanks for the answers!
     
  14. SF_FrankvHoof

    SF_FrankvHoof

    Joined:
    Apr 1, 2022
    Posts:
    780