Search Unity

GUI.matrix

Discussion in 'Immediate Mode GUI (IMGUI)' started by nickavv, Nov 6, 2007.

  1. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    Code (csharp):
    1. var originalWidth = 1024;
    2.  
    3. function OnGUI () {
    4.     var guiScale = Screen.width/originalWidth;
    5.     GUI.matrix = Matrix4x4.Scale(guiScale*Vector3.one);
    6. }
    I took this from an older topic and added an original width variable, but I get the error:

    "Ignoring invalid matrix assinged to GUI.matrix - the matrix needs to be invertible. Did you scale by 0 on Z-axis?
    UnityEngine.GUI:set_matrix(Matrix4x4)"

    I'm totally stumped since there's absolutely no documentation on GUI.matrix. Help! Thanks.
     
  2. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    I used this code to scale a GUI window a while ago:

    Code (csharp):
    1. GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(0, new Vector3(0, 1, 0)), new Vector3(FloatXSize, FloatYSize, 1))
    From what i remember, I was just Lerping the X and Y resize values to 'zoom' the window.

    cheers
    shaun
     
    andrew_pearce_ and fra3point like this.
  3. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    Use Matrix4x4.TRS(t, r, s) to create your matrix, then provide:

    t: translation vector value, move along x and y, but not z

    r: quaternion rotation value, rotate on z, but not x and y

    s: scale vector value, scale on x and y, but not z


    Edit: see this thread for another example of how to use GUI.matrix (look for my post near the end).


    Really quite a handy way to Translate, Rotate and Scale your GUI elements. Note that if you set the GUI.matrix then all GUI calls after that are affected by the matrix, so if you only want some elements affected then set the matrix value, issue your calls, then reset the matrix back to its original value.


    And yes, this is a weak point in the GUI docs so I'm sorry about that.
     
    Rond likes this.
  4. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    The only caveat is that when you scale GUI elements, they don't get filtered (in the way the Expose filters Mac windows) so things can get a bit jagged.
    Would be good to know if this can be changed.
     
  5. nickavv

    nickavv

    Joined:
    Aug 2, 2006
    Posts:
    1,801
    Alright, I'm getting something that works here. Thanks guys!

    Okay, new problem. :p
    Code (csharp):
    1.  
    2. var tScale = Vector3(1.0*Screen.width/1024, 1.0*Screen.width/1024, 1.0);
    3.     var tMatrix = Matrix4x4.TRS(tOffset, tRotation, tScale);
    4.     GUI.matrix = tMatrix;
    5.     if (reading) {
    6.         GUI.Box (Rect(262,0,500,150), showup);
    7.     }
    This is the code I'm using to scale the GUI, and the box that I'm making appear with it. Now the problem is that I want it to rest near the bottom of the screen, but different resolutions put it in different places, sometimes too high, and sometimes too low. How I got the 262 to be the center point for horizontal was this:

    1024 (value I'm scaling by)/2-500 (width of the box)/2.
     
  6. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    716
    Does that mean we can't make any perspective effects using rotation within the matrix?

    Cheers.
     
  7. shaun

    shaun

    Joined:
    Mar 23, 2007
    Posts:
    728
    There is no perspective applied to the GUI when you use Matrix (at least last time I tried it). The Matrix is meant to be used for 2D scaling and rotation.

    I used 3D rotation and it works, but it's a squash rather than tilt, if you know what I mean. The controls also get a bit funky if you try to use them in Matrix mode with 3D rotations.

    As of Flash 10 (Apollo), there will be GPU powered 3D (and 'Shaders' via Hydra). They showed off GUI rotation which looked cool. Video is here:
    http://drawlogic.com/2007/10/02/fla...dobe-image-foundation-and-hardware-rendering/
     
  8. thylaxene

    thylaxene

    Joined:
    Oct 10, 2005
    Posts:
    716
    stop teasing me with flash 3d stuff! not fair dude! :wink: lol

    cheers.
     
  9. bernardfrancois

    bernardfrancois

    Joined:
    Oct 29, 2009
    Posts:
    373
    Just found out the following code doesn't work:
    Code (csharp):
    1.  
    2. GUI.matrix.SetTRS(...);
    3.  
    Instead, the following needs to be used, as HiggyB explained above:
    Code (csharp):
    1.  
    2. GUI.matrix = Matrix4x4.TRS(...);
    3.  
    This behavior doesn't seem to make sense, so I submitted a bug report:
    http://fogbugz.unity3d.com/default.asp?436724_u8ak8heh95u7injb
     
  10. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Actually that behavior, while undeniably confusing, is correct. GUI.matrix is a property returning a struct. Properties of structs always return a copy of the struct instead of the original (since that is how structs work). Basically, you're applying your SetTRS(...) onto an anonymous copy of the GUI matrix. I do believe that the compiler is supposed to give a warning about this.
     
    Seneral likes this.
  11. KeinZantezuken

    KeinZantezuken

    Joined:
    Mar 28, 2017
    Posts:
    53