As this is my very first post on anything Unity3D related, I thought I would share this: The single, most powerful bit of code that I use. Every day. It’s not really that complicated, but before I discovered it coding for Unity’s GUI was a bit less pleasant.
What I’m referring to is a little tidbit that scales the entire GUI based on the resolution that the graphics were authored at. So without further ado..
C#
1 2 3 4 5 | public static void AutoResize(int screenWidth, int screenHeight) { Vector2 resizeRatio = new Vector2((float)Screen.width / screenWidth, (float)Screen.height / screenHeight); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(resizeRatio.x, resizeRatio.y, 1.0f)); } |
Javascript
1 2 3 4 5 | public static function AutoResize(screenWidth:int, screenHeight:int):void { var resizeRatio:Vector2 = Vector2(Screen.width / parseFloat(screenWidth), Screen.height / parseFloat(screenHeight)); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3(resizeRatio.x, resizeRatio.y, 1.0)); } |
What we do here is:
- Figure out the ratio of our current screen resolution compared to our authored resolution
- Set our current GUI transform matrix to a scaled one
Not too much too it right? Doing this allows you to use absolute sizes and positions when you are drawing your buttons, labels, textures etc. in the GUI. They will automatically scale up or down depending on your resolution.
Note: Using this approach you will want to avoid using Screen.width or Screen.height for sizes & positions to avoid double scaling.
AutoResize Function
AutoResize is public and static so we can define it once, and call it from anywhere. The function takes 2 parameters:
public static void AutoResize(int screenWidth, int screenHeight)
- screenWidth: the authored width of the game
- screenHeight: the authored height of the game
By authored resolution, I am referring to the resolution you intend the graphics to be viewed at.
For example: If I call AutoResize(1920, 1080), when I view the game at 1920×1080 resolution in full screen, my graphics will look 1 to 1 how they were created. If I view the game at any other 16:9 resolution, the graphics will scale up or down in size. At any other resolution however, say 1920×1200, the graphics will stretch as well as scale.
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | using UnityEngine; public class ScaleGUI : MonoBehaviour { public Texture2D Image; void OnGUI() { AutoResize(1920, 1200); GUI.DrawTexture(new Rect(0.0f, 0.0f, Image.width, Image.height), Image); } public static void AutoResize(int screenWidth, int screenHeight) { Vector2 resizeRatio = new Vector2((float)Screen.width / screenWidth, (float)Screen.height / screenHeight); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(resizeRatio.x, resizeRatio.y, 1.0f)); } } |
Here we create a simple C# class. We call AutoResize() first in OnGUI . What this does is scale everything after it this draw call within OnGUI. Important: AutoResize() must be called on every GameObject that would have any GUI content scaled.
Image now gets scaled on the screen according to how our actual resolution compares to the authored resolution.
GetResizedRect Function
As a bonus I’ll throw in this function which allows you to scale a single rectangle. You could also use it to figure out what Rectangles you are actually drawing, in case you need to test a Rect Contains() in the Update function or something.
C#
1 2 3 4 5 6 7 | public static Rect GetResizedRect(Rect rect) { Vector2 position = GUI.matrix.MultiplyVector(new Vector2(rect.x, rect.y)); Vector2 size = GUI.matrix.MultiplyVector(new Vector2(rect.width, rect.height)); return new Rect(position.x, position.y, size.x, size.y); } |
Concluding..
This is perhaps the most useful when mirroring a Standalone build in the Web Player. Most web builds are quite a bit smaller than a high res desktop build, and graphics that don’t scale down can get pushed right off the screen!
Be sure to make sure though that this technique suits your project before relying on it. When I am coding a project, typically it is GUI heavy and the target client’s resolution is not going to change. This technique is very convenient for this situation. If, however, your project targets a wide range of resolutions, this may not be the best technique to implement, as a portion of your users would have stretched graphics and be using textures much larger than necessary for their screen.
Enjoy!
Ben
Awesome man! Thanks so much for this. I’ve been looking forever for something as simple and easy to understand as your explanation!
Thanks!
Man Thank you! That helped me much 😀 THANKS
Wow thank you man! This definitely should be in GUI.matrix page on unity scripting reference!
thanks.Cool
Thank you, before I read this, I used Screen.width and Screen.height for each rectangle!
Really Nice snippet works perfect
Thanks a lot man! This tut is awesome because takes care about who script in C# and in javascript both!
Thanks buddy!
Thanks, just needed this!
thanks man, that quick and efficient