Search Unity

Question What can I do so that I create an image which isn't a square?

Discussion in 'Scripting' started by tomlugin100, May 25, 2023.

  1. tomlugin100

    tomlugin100

    Joined:
    May 6, 2023
    Posts:
    84
    I've been trying to create an image programmatically to place on my Canvas.
    I've been using this script which I found in these forums:
    Code (CSharp):
    1. public class Test : MonoBehaviour
    2. {
    3.     private Sprite img1;
    4.     public GameObject MyImage;
    5.     // Start is called before the first frame update
    6.     void Start()
    7.     {
    8.         GameObject MyImage =  new GameObject();
    9.         MyImage.AddComponent(typeof(Image));
    10.         img1 = Resources.Load<Sprite>("Platforms/platform");
    11.         MyImage.GetComponent<Image>().sprite = img1;
    12.         Debug.Log("Test script started");
    13.         myImage.transform.SetParent(gameObject.transform);
    14.     }
    15. }
    The image loads, but its a square. The image is stretched out vertically so it assumes the shape of a square with equal width and height. What can I do so that image is proper original dimensions? Thank you so much for your help
     
  2. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,113
    Sprite has a texture property, which is of Texture2D type and has width and height.

    Code (csharp):
    1. img1 = Resources.Load<Sprite>("Platforms/platform");
    2. Debug.Log($"w: {img1.texture.width} h: {img1.texture.height}");
     
  3. tomlugin100

    tomlugin100

    Joined:
    May 6, 2023
    Posts:
    84
    Thank you for your response @orionsyndrome . Are you saying I should try to access the texture 2D of the sprite?

    I tried to read the image data into a Texture 2D and then load the texture2d onto the canvas, but I still got a square. Then I did a lot of reading about how Unity and other game engines favor powers of two and squares, about which I hadn't known. So I settled on importing assets that are square and have a lot of transparent pixels underneath the images I need
     
  4. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    Image is always square. You can't avoid it. So you either need to size the square to match the size of your sprite or you have to go with a spriterender component. The image component uses the RectTransform, which has the width and height settings. While a SpriteRenderer uses the regular Transform component. You can use a SpriteRenderer on a canvas, but note the behavior is a little different.

    If you want to stick with UI Image component, then whatever sprite you are loading in, as @orionsyndrome mentioned, should have a width and height you can reference and set the width and height of your image component to so they match and it will not look squished or stretched.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    Don't create UI programmatically, it is a complete disaster.

    So much stuff gets set up in the editor when you make an Image or Text or whatever, it is essentially useless to try and make your own.

    Instead, pre-make what you need, hide it in the scene and clone it. See enclosed package for example.
     

    Attached Files:

    orionsyndrome likes this.
  6. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,113
    Yes and you're then you're expected to resize your Image with that info like @Brathnann suggested. All you need is really the aspect of the texture. This should work, though I haven't tried it, maybe I'm missing something obvious.
    Code (csharp):
    1. img1 = Resources.Load<Sprite>("Platforms/platform");
    2. var aspect = (float)img1.texture.width / (float)img1.texture.height; // these are both ints, you want float
    3.  
    4. // img1 is Sprite, the following line is about UnityEngine.UI.Image
    5. myImage.rectTransform.localScale = scalarScale * new Vector3(aspect, 1f, 0f);
    Something like that.
    You can also try setting preserveAspect to true.

    Also consider what @Kurt-Dekker is saying.
     
    Last edited: May 26, 2023
  7. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,113
    I tend to agree with Kurt because I never actually attempted to do UI completely programmatically. So there must be a reason for that. Usually you want a hybrid approach, you set up your objects through the editor and save them as prefabs. From that point on, you breeze through the code, and you get the best of both worlds.
     
    Kurt-Dekker likes this.
  8. tomlugin100

    tomlugin100

    Joined:
    May 6, 2023
    Posts:
    84
    Thank you guys for all your great answers! You've been a great help!