May 4, 2021
Flying Game
UI & Matrix Rotations
Overview
I wanted to make a 3D UI element which could direct the player in open flying space towards a point of interest or goal. This needed to point towards the object positionally, as well as account for the rotation or direction the player is facing. This makes sure that no matter where they are and what direction they are facing, it can guide them to turn the proper direction and make informed decisions to move directly towards that goal.
After deciding that changing my frame of reference could be a solution for this problem, I found Unity’s InverseTransformDirection method which can change a Vector from one space to another. To make sure this was providing a result similar to what I expected mathematically, I also wrote out the math for performing a matrix rotation on the vector and was happy to see it gave the same results.
3D UI Element – Real Time Guide Towards Goal
Add a 3D Element to the Unity Canvas
You change the render mode of the Canvas to Screen Space – Camera, which requires adding a Camera reference. To satisfy this, create another Camera separate from the main with the above settings. Drag this Camera in as the reference for your Canvas. Now 3D objects can be added to the Canvas.
Make sure the 3D elements added are on the UI layer. Sometimes the scaling can be strange, so you may need to scale the objects up substantially to see them on the Canvas. Also your main Camera may separately render the object as well, so to avoid this remove the UI layer from the Culling Mask for your main Camera.
-
Canvas Settings:
- Render Mode = Screen Space – Camera
- Render Camera = Created UI Camera
-
UI Camera Settings:
- Clear Flags = Depth only
- Culling Mask = UI
- Projection = Orthographic
Unity’s InverseTransformDirection to Set Guide Upward Ray
Using Unity’s “InverseTransformDirection()” method from the player’s transform with the vector pointing from the player’s position to the intended goal allowed me to change the frame of reference of the goal vector from world space to that of the player. This properly rotates the vector to associate itself with the player’s current rotation as well as their position relative to the goal.
Creating my Own Rotational Transformation on the Goal Vector to Compare to Unity’s InverseTransformDirection
To double check what this was doing, I found the math to change the frame of reference of a vector from one frame to another at the link attached. Since the player currently only rotates on a single axis (the y-axis in this case), I could directly copy the example seen in the video which investigates representing a vector in a new frame with a rotation about a single axis (to keep the terms simpler for now). Following this math I got the exact same results as Unity’s InverseTransformDirection method, indicating they perform the same operations.
Creates Vector from Player to Goal
private Vector3 PointTowardsGoal() { return goal.position - player.transform.position; }
Transforms Goal Vector from World Space to Player’s Space with Unity InverseTransformDirection
private Vector3 PointTowardsGoalRelativeToForward() { // Translate direction to player's local space relativeDirectionFromForwardToGoal = player.transform.InverseTransformDirection(PointTowardsGoal()); return relativeDirectionFromForwardToGoal; }
Transforms Goal Vector from World Space to Player’s Space with Rotation Matrix Math
private Vector3 GoalVectorInFrameOfPlayer() { // pr Vector3 originalVector = PointTowardsGoal(); // Obtain rotation value (in radians); Rotation angle about the y-axis float theta = player.transform.localRotation.eulerAngles.y * Mathf.PI / 180; // p1 Vector3 vectorInNewFrame = new Vector3( originalVector.x * Mathf.Cos(theta) - originalVector.z * Mathf.Sin(theta), originalVector.y, originalVector.x * Mathf.Sin(theta) + originalVector.z * Mathf.Cos(theta) ); return vectorInNewFrame; }
Flying Game Project: 3D UI Guide Towards Goal Prototype from Steve Lilley on Vimeo.
Flying Game Project: Comparing Unity's InverseTransformDirection to my Own Rotational Matrices from Steve Lilley on Vimeo.
Summary
It is good to know that for standard procedures where I want to change the relative frame of a vector that Unity’s InverseTransformDirection() method appears to do that. As showcased here, that can be a very strong tool when you need to translate vector information from your game’s world space to an element in your UI, whether that be through the player’s current frame reference or something else.
Learning how to setup a Canvas to use 3D assets in your UI is also good to know just to increase the flexibility of options you have when creating a UI. Some information can be difficult to convey with a 2D tool, so having that option can open avenues of clarity.
via Blogger http://stevelilleyschool.blogspot.com/2021/05/game-project-flying-game-part-2-3d-ui.html