GUI Texture scale and position according to the actual screen resolution..

Hi Everyone, how can I scale and position the GUITexture according to the current screen resolution. I don't want to use the built in GUI function which already include the scaling parameter.

This will center the texture based on the screen resolution and the image's aspect ratio (won't stretch it.)

private GUITexture myGUITexture;

void Awake()
{
    myGUITexture = this.gameObject.GetComponent("GUITexture") as GUITexture;
}

// Use this for initialization
void Start()
{
    // Position the billboard in the center, 
    // but respect the picture aspect ratio
    int textureHeight = guiTexture.texture.height;
    int textureWidth = guiTexture.texture.width;
    int screenHeight = Screen.height;
    int screenWidth = Screen.width;

    int screenAspectRatio = (screenWidth / screenHeight);
    int textureAspectRatio = (textureWidth / textureHeight);

    int scaledHeight;
    int scaledWidth;
    if (textureAspectRatio <= screenAspectRatio)
    {
        // The scaled size is based on the height
        scaledHeight = screenHeight;
        scaledWidth = (screenHeight * textureAspectRatio);
    }
    else
    {
        // The scaled size is based on the width
        scaledWidth = screenWidth;
        scaledHeight = (scaledWidth / textureAspectRatio);
    }
    float xPosition = screenWidth / 2 - (scaledWidth / 2);
    myGUITexture.pixelInset = 
        new Rect(xPosition, scaledHeight - scaledHeight, 
        scaledWidth, scaledHeight);
}

You can do this:

GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), aTexture);

Why don’t you want to use the built-in scaling function?

For anyone else searching for the most simple solution, you can create a script with the following:

// 
public Texture m_texture;

//
void OnGUI()
{
    // 
    GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height), m_texture, ScaleMode.ScaleToFit, true);
}

Then in the editor, just drag and drop the fullscreen texture into the script. It will scale to fit and won’t be cut off anywhere.

Attach a GUITexture to a game object and set the game object's transform to (0,0,0) for position, rotation, and scale. Now the pixel inset properties of the GUITexture control the screen position of the texture in pixels. (0,0) is the lower left, and (Screen.width, Screen.height) is the upper right.

I found the best way to do GUI texture sort of stuff is to create a simple 2 triangle plane and attach it to the camera.Once you’ve got it aligned how you want in the view, no matter the resolution or screen size it always looks good.

If you need to scale a power bar for instance, by default it scale smaller/larger from middle, thus affecting both ends.
To resolve this use the CreatePlane.cs script from the Unify wiki and set the anchor value to whatever anchor your scaling requires.

Not to mention you get away from using the ghastly OnGUI()

hello… i was trying to put the Fade script from unifycommunity.com into an application and was trying to resize my GUITexture into screen dimensions so i just checked in http://unity3d.com/support/documentation/Components/class-GuiTexture.html that i needed to have (0,0,0) for rotation, scale and position… and just add the next lines to my GUITexture:

function Start () 

{

guiTexture.pixelInset.x = 0;
guiTexture.pixelInset.y = 0;
guiTexture.pixelInset.width = Screen.width;
guiTexture.pixelInset.height = Screen.height;

}

and works very well… i hope that helps

The problem with getting rid of the pixel inset (for width and height) and using scale is that you cannot avoid that your GUI element will deform. So what I just tried is this. You use the transform position (at the GUITexture) to let the UnityEngine handle the position using screen coordinates as usual, but you control the width and height of the element setting the pixelInset yourself, based on a ratio that you calculate using your base screen height with the current screen height (or you could use width for the calculation). That way you ensure that both width and height of the image are multiplied by the same value and it keeps the same aspect ratio. To me, it seems to work fairly well. Try it and tell me what you think. The code used to update the pixelInset can be put in a monobehaviour in the same gameObject as the GUITexture. (If your screen size is not going to change during the game, you can do the calculus just once at the Start method.) The code is like this:

using UnityEngine;
using System.Collections;

public class GUITextureResizer : MonoBehaviour 
{
	private GUITexture _guiTextureRef;
	
	public const float BASE_WIDTH = 800;
	public const float BASE_HEIGHT = 600;
	
	private float _baseHeightInverted;
	
	private float _originalPixelInsetWidth;
	private float _originalPixelInsetHeight;
	
	void Awake()
	{
		_guiTextureRef = GetComponent<GUITexture>();
	}
	
	void Start() 
	{
		_baseHeightInverted = 1/BASE_HEIGHT;
		_originalPixelInsetWidth = _guiTextureRef.pixelInset.width;
		_originalPixelInsetHeight = _guiTextureRef.pixelInset.height;
	}
	
	void FixedUpdate() 
	{	
		float ratio = Screen.height * _baseHeightInverted;		
		
		_guiTextureRef.pixelInset = new Rect(0, 0, _originalPixelInsetWidth * ratio, _originalPixelInsetHeight * ratio);
	}
}

So, remember, you set your initial pixelInset width and height using the inspector of the GUITexture. The x and y for the pixelInset is set to 0. The scale of the transform is set to 0, 0, 1.

This is how it works:

I just saw that it does not preserves the distances to right edges, but it still works fairly well for must purposes I guess.

This is the most simple code for that…

CODE:

var native_width : float = 1200;
var native_height : float = 800;

function OnGUI ()
{	
var rx : float = Screen.width / native_width;
var ry : float = Screen.height / native_height;
GUI.matrix = Matrix4x4.TRS (Vector3(0, 0, 0), Quaternion.identity, Vector3 (rx, ry, 1));

//here goes your gui code (buttons,labels,etc..)
//warrning! use native_width not Screen.width !
//example: button in the middle of the screen
    GUI.Button(Rect(native_width*0.5-100,native_height*0.5-40,200,80), "Example!");

}

About that warrning in the comment, you are using your native width and height and then the gui matrix will scale your gui from native resolution to screen resolution.

Tested on xperia play 4’ and xperia tipo 3,2’ and on laptop 15,6’. Work’s like a charm :slight_smile:

I’d just wait, until unity 5’s new gui canvas system.

Hey guys,
I had the same problem with a few textures that i wanted scaled over the screen. when the resolution changed, they didn’t. irritating.

Discovered that if you leave the pixel inset alone and just change the scale of the texture itself, it scales to the resolution.

Don’t know if that would help anyone but if someone had the same issue as me, it might.

This is what i use, replace the 570 and 380s with the resolution you’re currently working on, somtimes it causes a little streching on the textures.

function Start () {

	var DivideX= 570/guiTexture.pixelInset.x;
    var DivideY= 380/guiTexture.pixelInset.y;
	var DivideWidth=570/guiTexture.pixelInset.width;
	var DivideHeight=380/guiTexture.pixelInset.height;
	
	guiTexture.pixelInset = Rect(Screen.width/DivideX,Screen.height/DivideY,Screen.width/DivideWidth,Screen.height/DivideHeight);
	
}