Search Unity

Image Disappearing when I assign a Sprite

Discussion in 'Scripting' started by PeteMichaud, Aug 13, 2015.

  1. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    I have a prefab that has an Image UI component. In the editor I don't assign any Sprite to it, so it's just a solid white square in the editor. When I run my game all the instances that use the prefab also have a solid white square.

    I have a script that generates a Texture2D, and the idea is that for that Texture2D to be displayed in the Image of that prefab. So I assign the texture to a new Sprite, and I assign the sprite (in code) to the Image component.

    When that happens, the pictures disappears entirely, like it's not there at all. Here's some relevant code:

    https://gist.github.com/PeteMichaud/14308106832489f1c029

    I've tried using a RawImage and assigning the Texture2D to that, but that has the same outcome.

    Out of curiosity I assigned an outline component to the image which shows up fine when no sprite is assigned (it's a black outline around the white square). When I assign the sprite, everything including the outline is invisible, which seems like a good clue, but I don't know what it means. I tried that with both Image and RawImage.

    I'm totally at a loss. What am I supposed to do?
     
  2. lineupthesky

    lineupthesky

    Joined:
    Jan 31, 2015
    Posts:
    92
    I don't have that much of an idea about Texture creation, but can you try this:

    Make the component RawImage, lets just not deal with sprites for now.
    Just create a Texture2D variable on your script, drag&drop any texture on it over the inspector, again find your instantiated prefab, and try attaching that Texture2D on the prefab, not the texture that you create via script.

    If the prefabs accept the texture that you assing correctly ( any texture that you dragged&dropped to the Inspector on the variable field ), then we can be sure that there is no problem on the "finding" part of your scripts, neither on the UI settings of your prefab, then the problem must be because of "Texture Creating" via scripting.

    If it's still invisible, the problem is probably the script is not finding the right prefab, you need to debug it.

    This way we can understand if the problem is about finding your prefab, or prefab's UI settings, or the texture that you create. I know I couldn't give a solid answer, but doing the checks that I've advised may lead the next person who knows the topic in to the right way.
     
  3. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Hey lineupthesky, thanks for your help. I actually don't know how to create a Texture in the editor. One thing I've already done is have a panel that has an image component, and used a jpg I put in my assets folder to drag onto the image source (that works fine, showing the image as expected). I thought that image I was dragging had been internally converted to a Sprite, but maybe I'm confused and it's actually a Texture2D?

    For what it's worth, I do know some things about what you're pointing at (all of these things I know for sure because I verified them in the debugger at runtime):

    1. The texture I create is getting an array of Color32s that are the correct color
    2. That color array is being assigned and applied without throwing any exceptions.
    3. Once GenerateTexture is done, the result is in fact a Texture2D instance (I'm not sure what it actually contains, beause when I try to watch the output of "texture.GetPixel(1,1)" it immediately crashes Unity every time).
    4. The Image component is definitely being found on the gameobject, I get an instance of it without error
    5. The generated texture is being successfully assigned to the rawImage.texture which I verify by watching rawImage.texture after the assignment

    So, it seems to be like the texture isn't generating correctly, but everything I can verify leading up to the texture creation seems like it's working fine. And I'm baffled about the outline disappearing--isn't it the case that if the texture were fully transparent, say, that I'd see my white square with a black outline replaced with a transparent square with a black outline?
     
    Last edited: Aug 13, 2015
  4. lineupthesky

    lineupthesky

    Joined:
    Jan 31, 2015
    Posts:
    92
    Thanks for writing your results of debugging, as I said, I won't be able to help much, but those debug results will help other users to rule out other possibilites and only focus on the one topic, which seems like the texture generation part of your script.

    I hope someone will be able to point you out in the right direction or fix the code, good luck!
     
  5. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    After writing that I tried something different. Like I said, after I Apply the changes to the testure, Unity was crashing when I tried to GetPixel(1,1), so instead I wrote some code in there right after the apply that both fetched the Color32[] array again and got the pixel at 1,1 -- when I did that and examined the values of those variables, I saw the correct colors in both cases.
     
  6. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    You are making a Color32... take a look in your RandomColor.Get (); and MainColor.GetComplement(); to make sure you are setting the .alpha value to 1.0f, otherwise the color will be right but it will be transparent.
     
  7. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Yeah, that's one of the first things I checked, alpha is definitely 1 on all colors (GetComplement actually returns the alpha of the instance color, but that is always 1 in this case, so all alphas are always one). All verified through the debugger.
     
  8. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    Perhaps subdivide the problem more by using Resources.Load<Texture2D>() to get a preset texture off the disk and make the sprite from that?
     
  9. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Ok, I replaced the body of GenerateTexture() with Resources.Load<Texture2D>("Images/background"), and that worked when I assigned the texture to a rawimage. That's progress, yay!

    So now it looks like something is wrong with GenerateTexture:

    Code (CSharp):
    1. Texture2D GenerateTexture()
    2. {
    3.         Texture2D t = new Texture2D(AVATAR_SIZE, AVATAR_SIZE); // 512
    4.  
    5.         Color32[] fillColorArray =  t.GetPixels32();
    6.        
    7.         for(var i = 0; i < fillColorArray.Length; ++i)
    8.         {
    9.             fillColorArray[i] = BackgroundColor;
    10.         }
    11.        
    12.         t.SetPixels32( fillColorArray );
    13.  
    14.         t.Apply();
    15.         return t;
    16. }
    But when I debug, everything seems to me like it should. All the colors look right, all the pixels that I look at after I apply things look right too. I'm missing something, I just don't know what it is.
     
  10. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Ok, here's something interesting:

    I replaced the last line of the function before the return with:

    Code (CSharp):
    1. t.Apply(false, false);
    2.  
    And now the image is filled with middle gray.

    If I just call it with one false I get a bunch of stack overflow errors that I'm currently looking at, and will report what I find.
     
  11. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Now when I call it with just one false I don't get any errors, and I can't reproduce that. Just getting the middle gray. When I check the value of the Color32 at 0,0 it's a random color, but something like (0,100,50,255), definitely not a middle gray.
     
  12. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Ok, another interesting thing. If I comment out everything in the GenerateTexture function except t.Apply(false) and return the texture, it returns the same middle gray. That tells me that that code isn't really doing anything. Why might that be?
     
  13. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Yeah, I've also tried SetPixel(0,0, color) with a new Color(255,0,0) instead of a Color32, and it's still just solid gray. For some reason I can't set pixels to my texture, and now I'm stuck. I don't know how to troubleshoot from here.
     
  14. PeteMichaud

    PeteMichaud

    Joined:
    Jul 11, 2015
    Posts:
    25
    Holy crap, I figured it out.

    1. I updated to Apply(false) because it gave me gray instead of nothing
    1. In my internals, I was generating a Color32 with an alpha of 1, which I thought was like 100% but was actually 1 out of 255, aka, almost transparent.

    So when I updated to 255, nothing seemed to change. I realized later that I needed to do Apply(true) aka Apply(). After I updated the alpha and set the first arg to true, it all started working.

    Thank god.
     
  15. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,686
    HA! I have been bitten by precisely this same bug a few years back when I was working with the Allegro game engine. And I mean precisely: I had been working with float,float,float colors somewhere else (maybe Unity?) and didn't realize I was now working with byte,byte,byte colors, since my one visible example was 0,0,0.

    Good catch! Glad you're operating now.