Search Unity

making a GUIContent.Texture larger than its actual file size

Discussion in 'Immediate Mode GUI (IMGUI)' started by benblo, Dec 7, 2007.

  1. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    Hi there! I've been running in circles all morning so I guess it's time to get help...

    I need to have a full-screen transparent texture on top of some GUI elements (buttons etc).
    It appears that an old GUITexture is always behind a GUI 2.0 element, so I need my texture to be a 2.0 element too. Why not.

    So I'm using GUI.depth to layer my elements, and it works fine. But now my texture cannot grow larger that its actual size, even though I checked "stretch width" and "stretch height" in my GUISkin.

    So... does anyone know a way to make an GUI2 image larger than its size?



    As a side note, I had a hard time finding GUI.depth because it isn't called z-index as is common, but it was worth it because I had the overwhelming pleasure to discover it's ordered in reverse from the old GUI system that used position.z (which was, again, the common order: bigger numbers go in front)... nice one UT :p.

    Oh, second one, GUI skins have "stretch width / height" properties, while script-side it's called GUILayout.ExpandWidth / Height()...
     
  2. nafonso

    nafonso

    Joined:
    Aug 10, 2006
    Posts:
    377
    Are you adding the texture (i.e. like an icon) to a GUI Box? If so, I believe that the size should always be the same of the texture. The only way that I think you could use to make it bigger could be to scale the GUI.matrix (BTW, if you want to change the matrix, use GUI.matrix = Matrix4x4.TRS(....) and not GUI.matrix.SetTRS(...), since Matrix4x4 is a struct and this will not work! Took me a bit of a time to figure that one out.....).

    But why don't you create a Box with a different style? Change the Box's default texture to the texture that you want to use.

    Regards,
    Afonso
     
  3. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    Obrigado nafonso!

    Actually I just found out that setting style.normal.background instead of GUIContent.image does stretch the texture to the size of the element, so yay, problem fixed!
    This works for any element, button, label, box, just put all borders to 0.

    I'm afraid I didn't get the Matrix thing but if someday I have another need I'll think about it ;) !


    For the record, I used a GUI.Label (since there's no GUI.Image... with no padding by default or something... that would have been nice), with a custom style to display ImageOnly.
    GUI.Box(myImage) behaves the exact same way.


    Also you say that "the size should always be the same of the texture"... nop, it's actually scaled down automatically if the element is smaller, that's why I found it weird that it's not scaled up...
    I've even seen a post saying "what if I don't want it scaled down?". I add: what if I want it stretched, or tiled?

    Até mais cara ;) !
     
  4. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    The next release contains a function that has lived under the internal name of JustDrawTextureGoddammit... Guess what it does :)
     
  5. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    Well, that's good to hear, every time I want to just-draw-a-texture-dammit, my finger slips and tries GUI.Image() but Intellisense stubbornly refuses to find it ;) !

    Will there be stretch/tile etc options? Tiling would be so neat... I've sent a request about it, case #16432.
     
  6. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    No tiling for now, but various StretchToFillWhileMaintainingAspectRatio kinda thingies are there
     
  7. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    JustDrawTextureGoddammit sounds like a great idea.

    Do you have any tips on how to achieve the same result with the current version of Unity?

    I would like to simply draw a texture on top of everything so it fills the whole screen. It's ok if the texture gets stretched to match the screen coordinates.

    I'm a Unity beginner. Isn't there something in GUI that allows to simply cover the whole screen?
     
  8. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    When I connect this script to the camera, it almost works.

    Code (csharp):
    1. var fadeTexture : Texture2D;
    2.  
    3. function Start () {
    4. fadeTexture.Resize(Screen.width,Screen.height);
    5. }
    6.  
    7. function OnGUI () {
    8. GUI.Label (Rect (0,0,Screen.width,Screen.height), fadeTexture);
    9. }
    Except that the texture turns black and it does not fill the entire screen.
     
  9. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    I managed to fill the entire screen by using a custom style:

    Code (csharp):
    1. var fadeTexture : Texture2D;
    2. var totStyle : GUIStyle;
    3.  
    4. function Start () {
    5. fadeTexture.Resize(Screen.width,Screen.height);
    6. }
    7.  
    8. function OnGUI () {
    9. GUI.Box (Rect (0,0,Screen.width,Screen.height), fadeTexture, totStyle);
    10. }
    It's still black, though...
     
  10. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    You want to assign the texture to the normal.background property of you guiStyle - and not do any rescaling.
     
  11. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    That works perfectly. :)
    Thank you!
     
  12. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    This does not, however, seem to work with a RenderTexture that is the size of the screen.

    I get "Cannot convert 'UnityEngine.RenderTexture' to 'UnityEngine.Texture2D'".
     
  13. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    Both Texture2D, and RenderTexture inherit from Texture, which is what the GUI calls want. So make your reference Texture instead of Texture2D.

    Texture2D is a Texture, RenderTexture is a Texture, but a RenderTexture is not a Texture2D, thus the conversion error. :)

    Cheers,
    -Jon
     
  14. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    Thanks for the tip. Sounds good.

    But I coded it like this:

    Code (csharp):
    1. var totStyle : GUIStyle;
    2. private var closeUpTexture : Texture;//instead of RenderTexture
    3.  
    4. function Start () {
    5. closeUpTexture = RenderTexture(Screen.width,Screen.height,0);
    6. camera.targetTexture = closeUpTexture;
    7. }
    8.  
    9. function OnGUI () {
    10. totStyle.normal.background = closeUpTexture;
    11. }
    And it doesn't work. Now I get "Cannot cast from source type to destination type".
     
  15. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
  16. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    It works with a Box.
    Code (csharp):
    1. GUI.Box (Rect(0,0,closeUpTexture.width,closeUpTexture.height),closeUpTexture,totStyle);
    I mean: the image displays correctly. But despite of that, I get an error message that says "Error assigning 2D rectangle texture to 2D texture property '_MainTex': Dimensions must match". Should I ignore the error message? Or is there something I need to change or add?
     
  17. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    Well... I'd say it expects a square texture are your RenderTexture isn't square... so changing your camera aspect ratio or something should rid you of the warning.

    BTW, sorry to barge in on the discussion, I still get topic updates in my mail but I didn't follow thoroughly ;), so I hope I'm not way off.
     
  18. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    Thanks. This may be a good tip. So how does one change the camera's aspect ratio?..

    And what should it be set to?
     
  19. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    Go to your cam > "normalized view port rect".
    The aspect ratio is width/height (or the contrary, I can never remember), but that's relative to the screen.

    • You want it to be square (1:1), if I got the error message right.
    • Now most likely your screen will either be 16:10 or 4:3 (or maybe 32:10 if you're a millionaire and you own a curved Alienware screen, but let's say it's 4:3 to simplify).
    • So if your cam occupies 1:1 of the screen, its aspect will be 4:3.
    • So... set height to 1 and width to .75 (= 1/4:3, or 3/4), and bam, you've got yourself a square cam.

    Now of course you'd have to script it to cover every possible resolution/ratios. And also maybe you don't want your texture to be square, in which case you're boned from the start.
    I could also be talking nonsense from the start, as I'm only interpreting from the error message you gave but never played with RenderTextures myself... who knows?
     
  20. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    Thanks for the instructions. But my RenderTexture is the same size as the screen. So not square.

    How do shaders do this in Unity?
    Perhaps I can borrow that technique to draw a fullscreen image on screen?

    It does work with a GUI Box. Despite of the error message. Is the error message wrong perhaps?
     
  21. benblo

    benblo

    Joined:
    Aug 14, 2007
    Posts:
    476
    I'm not sure I understand what you're trying to do... you render a texture from a cam then display it fullscreen?
    Seems like a duh question but... why don't you use the cam directly? Are you postprocessing the texture?

    Anyway, you may want to have a look at the old GUI, just create a GUITexture (from the GameObject menu), set transform.scale to (1,1,1) and pixelInset to (0,0,0,0) and bam, your texture fills the screen.
    I suppose it should accept a RenderTexture.
     
  22. JohnyZuper

    JohnyZuper

    Joined:
    Jan 7, 2008
    Posts:
    174
    I want to create a transparent overlay over the scene. Basically like a double exposure photograph, I guess.

    I'll have a look at the GUITexture.