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

Change in sprite renderer works correctly on a placed prefab, but not an instantiated one.

Discussion in '2D' started by Th0masThe0bvious, Feb 16, 2021.

  1. Th0masThe0bvious

    Th0masThe0bvious

    Joined:
    Aug 22, 2018
    Posts:
    80
    I have a game with multiple objects, some with multiple sprites, and many are placed at the start but a fair amount of them are also instantiated. I've never had this problem on any of them before, but all of a sudden I do, with just this one prefab. I might post code but I don't think that is needed, because after hours of looking over this code, as well as the code of objects that work correctly, I discerned that oddly enough, this is only a problem if I instantiate the objects. If I have an object in the scene already, then the code and sprites work perfectly. In fact, to test just what might be wrong I added a public int called "spriteInt" to change its number at the same time as the sprite renderer was supposed to change, and this number very clearly changes just fine.

    What could be wrong here? Please let me know,
     
  2. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,319
    Do I understand correctly?

    Scenario A: you place a prefab into the scene manually through the Editor. Then instantiate the same prefab. It works?

    Scenario B
    : you instantiate a prefab in scene without placing any in the scene beforehand. It doesn't work?

    And the thing that's failing is assignment like
    spriteRenderer.sprite = someSprite;
    ... correct? What appears instead? No sprite at all? The previous sprite stays?
     
  3. Th0masThe0bvious

    Th0masThe0bvious

    Joined:
    Aug 22, 2018
    Posts:
    80
    Whether I've placed in the prefab or not doesn't affect the outcome. I just re-tested the project with two of those objects placed into the scene before pressing Play, then after playing instantiated two more. The ones placed before change sprites correctly; the ones instantiated (that is, the ones with "Clone" in their name) do not.

    The previous sprite stays.
     
  4. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,319
    Try
    Code (CSharp):
    1. Debug.Log($"1: {spriteRenderer.sprite}");
    2. spriteRenderer.sprite = null;
    3. Debug.Log($"2: {spriteRenderer.sprite}");
    4. spriteRenderer.sprite = someSprite;
    5. Debug.Log($"3: {spriteRenderer.sprite}");
    What happens then?
     
  5. Th0masThe0bvious

    Th0masThe0bvious

    Joined:
    Aug 22, 2018
    Posts:
    80
    I'm sorry; please clarify: Am I supposed to copy that all totally as is into my code? Do I drag something into the inspector for "someSprite"? And to which part of my code does that code go?
     
  6. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,319
    Somewhere you're setting your sprite to the SpriteRenderer. I don't know what this is called in your code, so I'm calling that someSprite. Where you're doing the assignment that's failing, copy the debug statements and nulling there. Unless I misunderstand how you're doing the assignment then clarify that.
     
  7. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,319
    Alternatively / in addition, try this:
    Code (CSharp):
    1. public class SpriteTest : MonoBehaviour
    2. {
    3.     SpriteRenderer sr;
    4.     public Sprite spriteA; // assign something in Inspector
    5.     public Sprite spriteB; // assign something in Inspector
    6.     int which;
    7.  
    8.     private void Awake()
    9.     {
    10.         sr = this.GetComponent<SpriteRenderer>();
    11.     }
    12.  
    13.     private void Update()
    14.     {
    15.         if (which == 0)
    16.         {
    17.             sr.sprite = spriteA;
    18.             which = 1;
    19.         }
    20.         else
    21.         {
    22.             sr.sprite = spriteB;
    23.             which = 0;
    24.         }
    25.     }
    26. }
    This should flip the sprite every frame. Assign to the same gameobject that has the problematic SpriteRenderer. It should work whether prefab in scene or instantiated.
     
  8. Th0masThe0bvious

    Th0masThe0bvious

    Joined:
    Aug 22, 2018
    Posts:
    80
    OK, so I tried this. Initially it worked, to a point, but activating a void caused its sprite to stick at the first one. I had assumed that there was something in my original code that was screwing this up, so I went and deleted large portions of it. Now, the introduced animation code doesn't work at all. Except. as with before it was implemented, it works if the object is in the scene to start. There is something terribly wrong with this prefab and I'm thinking of deleting it and making a new one from scratch.
     
  9. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,319
    The problem sounds to me like something somewhere is competing to set the sprite every frame. Sounds very odd. Launching a coroutine or something? Are you using the Animator or animating the sprite changes yourself?
    Might be faster.
     
  10. Th0masThe0bvious

    Th0masThe0bvious

    Joined:
    Aug 22, 2018
    Posts:
    80
    I'm not using an animator. I didn't see the point in an object that doesn't really animate; only change between static images. Especially since every other object I've coded like this has been fine.
     
  11. Th0masThe0bvious

    Th0masThe0bvious

    Joined:
    Aug 22, 2018
    Posts:
    80
    So, I made a new object. I gave a total of one script, consisting only of your code. As it happens, there is still a difference between how the placed and instantiated versions function. Both of them have their sprite renderers say that things are changing, but only the pre-placed version actually displays it.

    At this point, it is safe to say that whatever is going on in my project isn't just a flaw with one object. It is a flaw that, despite not being present before, now affects any instantiated objects, preventing them from working as pre-placed objects do.

    Edit: I reported this bug. The version of Unity I was using was no longer supported, so I upgraded slightly and it seems it's been fixed. I want to be sure nothing has been broken by the update so bye and sorry for this long dive into something that's seemingly been solved by patching.
     
    Last edited: Feb 18, 2021
  12. Lo-renzo

    Lo-renzo

    Joined:
    Apr 8, 2018
    Posts:
    1,319
    No worries, these things happen.