Get the FULL version

Unity: Creating GUI transitions

Unity: Creating GUI transitions thumbnail

This Unity scripting tutorial shows how to manipulate the GUI system origin to create an animated transition, so you can make your GUI’s look more interesting. To keep things simple, this post shows how to create an horizontal transition between two Text Areas using a couple of buttons. All code featured below is available for download at the end of the post.

To achieve an animated transition, the origin of the GUI system must be manipulated. This is done by changing the elements of the matrix that sets the rendering reference point of the GUI elements. Conveniently, Unity allows us to do that by manipulating the GUI.matrix values. So, the script requires a Matrix4x4 object. Also, to make the code more readable, a Vector3 is going to be created, also making it easier to translate the GUI system origin. Here’s the script:

using UnityEngine;
using System.Collections;

public class HorizontalTransitionGUI : MonoBehaviour
{
	//A 4x4 Matrix
	private Matrix4x4 trsMatrix;
	//A three dimension vector that will translate GUI coordinate system
	private Vector3 positionVec;
	//Two booleans to determine which of the GUI buttons have been pressed
	private bool next = false;
	private bool back = false;

	// Use this for initialization
	void Start()
	{
		//Initialize the matrix
		trsMatrix = Matrix4x4.identity;
		//Initialize the Vector
		positionVec = Vector3.zero;
	}

	// Update is called once per frame
	void Update()
	{
		//If the 'next' boolean is true
		if(next)
		{
			//Interpolate the current vector x component until it has the same as value the screen width
			positionVec.x = Mathf.SmoothStep(positionVec.x, Screen.width,Time.deltaTime*10);
			/*Make 'trsMatrix' a matrix that translates, rotates and scales the GUI.
			The position is set to positionVec, the Quaternion is set to identity
			and the scale is set to one.*/
			trsMatrix.SetTRS(positionVec , Quaternion.identity, Vector3.one);
		}
		else if(back) //If 'back is true'
		{
			//Interpolate the current vector x component until it reaches zero
			positionVec.x = Mathf.SmoothStep(positionVec.x, 0,Time.deltaTime*10);
			//Make 'trsMatrix' a matrix that translates, rotates and scales the GUI.
			trsMatrix.SetTRS(positionVec , Quaternion.identity, Vector3.one);
		}

	}

	void OnGUI()
	{
		//The GUI matrix must changed to the trsMatrix
		GUI.matrix = trsMatrix;

		//If the button labeled 'Next' is pressed
		if(GUI.Button(new Rect(Screen.width - 400, 315, 100, 30),"Next"))
		{
			next = true;
			back = false;
		}

		//The TextArea that appears on the first screen.
		GUI.TextArea(new Rect(300,200,Screen.width-600,100), "Click on the 'Next' button to change the Text Area.");

		//If the button labeled 'Back' is pressed
		if(GUI.Button(new Rect(-Screen.width + 300, 315, 100, 30),"Back"))
		{
			next = false;
			back = true;
		}

		//The TextArea that appears on the second screen
		GUI.TextArea(new Rect(-Screen.width + 300,200,Screen.width-600,100), "Click on the 'Back' button to return to the previous Text Area.");

		//To reset to GUI matrix, just make it equal to a 4x4 identity matrix
		GUI.matrix = Matrix4x4.identity;

		//A Label that won't change position
		GUI.Label(new Rect(300,350,500,100),"This Text Label remains at the same position, no matter what.");
	}
}

Right at the top of the script, a Matrix4x4 object, a Vector3 and a pair of boolean variables are being declared. As previously stated, the Matrix4x4 is going to be the one that will replace the GUI matrix later on the code. The Vector3 is there to aid in the task of building the aforementioned Matrix4x4 as a translation matrix. The pair of booleans are declared to tell if one of the buttons have been pressed (lines 7 through 12).

At the Start() method, the Matrix4x4 is initialized as a identity matrix and the Vector3 objects is initialized as a a null vector (lines 15 through 21). The Update() method is where it all happens. In the above script, it’s basically a if else block that checks whether the value of the next and previous booleans are true or false; changing according to the button pressed at the interface (lines 24 through 44). If next is true, the positionVec X component is interpolated the SmoothStep() method, which takes three parameters.

The first one is the value the interpolation is going to start, the second is the value where the interpolation ends and the third, can be thought as the speed which in the interpolation must happen. In the above script, the parameters are, respectively: the positionVec X component, the screen’s width and the Time.deltaTime value multiplied by 10 (line 30). So, what will happen is that the X component of postionVec will be gradually interpolated using the third parameter until the X component of the Vector3 has the same value as the screen width. Effectively, this will move the whole GUI system origin out of the screen when it’s matrix translated with the recently interpolated component of the Vector3.

To create a translation matrix, the TRS() method is called from the Matrix4x4 object, taking three parameters. The first one is going to be positionVec and since the rotation and scale of the GUI system must remain the same, the second and third parameters are filled with Quaternion.identity and Vector3.one (line 34). That’s it! With that, all that’s necessary is to replace the GUI.matrix with the trsMatrix. This can only be done inside the OnGUI() method, which starts at line 46 and ends at line 76.

After replacing the GUI coordinate system with the trsMatrix at line 50, some elements are being rendered, namely a pair of Buttons elements, two TextAreas elements and a Label. All elements, except for the Label are being rendered with their X position relative to the screen’s width. That’s because the GUI’s system reference X value is going to be shifted from zero to Screen.width at the Update() method, so it makes sense to make everything dependent on the screen width. The Label doesn’t change position because the current GUI.matrix it’s using as the reference for positioning is the identity matrix.

Also, the two buttons declared here changes the value of the next and previous boolean variables accordingly. It’s worth mentioned that the OnGUI() method resets the GUI.matrix to identity each call, so line 75 (the GUI.Label() method call) could be placed before line 49 (GUI.matrix = trsMatrix;), yielding the same results.

Final Thoughts

Some readers might be wondering why manipulate the GUI system matrix to create a simple horizontal transition when the same could be easily done by changing the X coordinate of a GUI group. And surely, some are wondering why use the Matrix.TRS() method to make a simple translation, when all it takes is to change the last element of the first line of the trsMatrix (trsMatrix.m03).

For the above example, the aforementioned alternatives could easily be used as it’s just a simple horizontal translation. However, for more complex transitions, such as the ones that changes the rotation and the scale, a matrix is necessary. Remember that, in Unity, there’s no way to change the scale or rotation of some GUI element without altering the current GUI.matrix. Furthermore, on those cases, changing the GUI.matrix is necessary.

Here’s a video of the transition code in action:

Downloads

6 Comments to “Unity: Creating GUI transitions”

  1. Simon says:

    Thanks for this,

    Very clear, got me out of a Jam.

    Keep up the good work mate.

  2. Dreadkill says:

    Hi…can you give us some tips on how to position the GUI transition to bottom???

  3. jenny says:

    thanks man… you’re the best :D

  4. jenny says:

    i want a translation to right to left how ?

Leave a Comment

Post Comments RSS