Search Unity

Drop lists and creating a sprite with a dynamically-generated Texture2D

Discussion in 'Scripting' started by VCC_Geek, Sep 14, 2018.

  1. VCC_Geek

    VCC_Geek

    Joined:
    Apr 30, 2013
    Posts:
    29
    So I beat my head against the wall on this for a good two hours, so to save others the unpleasant experience, here's the answer. There are actually several problems, but they're all related, so I'm putting them in one post.

    Situation: You're creating a Texture2D on the fly, using that to create a Sprite, and then assigning that to a component that has a Sprite slot (such as a UI image).

    Problem: 1) The image comes out completely gray, and/or 2) you're doing several, and they all come out identical to the last one.

    Solution: First off, make sure you call Apply() in your Texture2D object before you use it to create your sprite. Setting pixels only sets the data structure - it does not actually update the image. I'm assuming this is to allow for texture compression. Second, do NOT reuse the Texture2D object. Make a new one for each sprite you create. Apparently, Unity keeps the Texture2D around when it creates the sprite - calling SetPixels() on it will update the original - at least, that's the way it worked out when I did it. I ended up creating a new one inside the loop. Creating the variable ouside the loop, and then reusing the variable inside the loop with the Texture2D constructor, made all of the sprites come out identical to the last one. (If anyone knows a better explanation of why it came out like this, I'm interested in hearing it.)

    So your code should look something like this:
    Code (csharp):
    1.  
    2. for (int i = 0; i < listItems.length; i++) {
    3.  
    4.     // create the texture
    5.     Texture2D tex = new Texture2D(100, 20);
    6.  
    7.     // define a rect for it to live in
    8.     Rect rect = new Rect(0, 0, 100f, 20f);
    9.  
    10.     // define your pixels - it's an array of colors
    11.     Color [] colors = getColorsFromAnotherMethod();
    12.  
    13.     // set the data structure
    14.     tex.SetPixels(0, 0, 100, 20, colors);
    15.  
    16.     // apply it and update the image.
    17.     tex.Apply();
    18.  
    19.     // create the sprite
    20.     Sprite sprite = Sprite.Create(tex, rect, Vector2.zero);
    21.  
    22.     // enjoy your new sprite
    23.     doSomethingWithThis(sprite);
    24.  
    25. }
    26.  
    As for the correctness of this code, I refer you to my signature. :)

    Another problem I ran into: When creating a drop list ("Dropdown" UI element, I've always called them combo boxes or drop lists), you're trying to add a sprite to it in code, but it never shows up. If you're wondering, this is what I was doing with the dynamically-generated sprites: populating a drop list automatically.

    Solution:
    1. In your scene view, find the drop list, expand it out, and drill down to Template->Viewport->Content->Item.
    2. Highlight your drop list object.
    3. Underneath Item, drag "Item Background" to the "Item Image" slot in the Dropdown component.
    4. Now, duplicate the "Item Background" object, and drag it within the scene view, to the drop list object, so that it's a direct child of that object. Rename it if you want. I'm a stickler for naming conventions, but that's just me.
    5. Unity is going to auto-adjust the RectTransform so that it doesn't move, so you will need to adjust to taste. (I tried Raw Edit mode, but apparently it doesn't help with that.)
    6. Highlight your drop list object again, and drag that new background into the "Caption Image" slot.

    You should be all set. If not, go through the steps again and post in this forum, but I'm not sure I can help if you're still having problems.

    I hope this saves someone the splitting headache I had after all was said and done. : P
     
    Last edited: Sep 15, 2018