Description: https://images.manning.com/360/480/resize/book/8/ef327d5-f4c9-4bec-a7f1-968696efef70/Hocking-Unity-3ed-MEAP-HI.png

This commodity is an extract from affiliate 8, in which the reader learns to plan movement controls for a character that has been imported into Unity.


Have 35% off Unity in Action, Third Edition by entering code fcchocking3 into the discount code box at checkout at manning.com.


Once a character model is imported into Unity, it's time to plan controls for moving around the scene. Allow's programme photographic camera-relative controls that'll move the graphic symbol in various directions when arrow keys are pressed, besides every bit rotate the graphic symbol to confront those different directions.

What does "camera-relative" mean?

Implementing camera-relative controls involves ii master steps: offset rotate the actor graphic symbol to face the direction of the controls, and then motion the graphic symbol forrard. Allow's write the lawmaking for these ii steps next.

Rotating the character to face move management

Start y'all'll write code to make the character confront in the direction of the pointer keys. Create a C# script called RelativeMovement, and write the code from listing 1. Drag that script onto the thespian character, then link the photographic camera to the target property of the script component (but as y'all linked the character to the target of the camera script). Now the character volition face unlike directions when y'all press the controls, facing directions relative to the camera, or stand up yet when yous're not pressing any arrow keys (that is, when rotating using the mouse).

Listing ane. Rotating the grapheme relative to the photographic camera

    using Organization.Collections;  using Organisation.Collections.Generic;  using UnityEngine;     public class RelativeMovement : MonoBehaviour {      [SerializeField] Transform target;                        #A           void Update() {          Vector3 motion = Vector3.zip;                              #B             float horInput = Input.GetAxis("Horizontal");          bladder vertInput = Input.GetAxis("Vertical");          if (horInput != 0 || vertInput != 0) {                        #C                 Vector3 right = target.right;              Vector3 forward = Vector3.Cross(right, Vector3.up);       #D              movement = (correct * horInput) + (forward * vertInput);    #E                 transform.rotation = Quaternion.LookRotation(move);   #F          }      }  }        

#A This script needs a reference to the object to motion relative to.

#B Start with vector (0, 0, 0) and add movement components progressively.

#C Only handle move while arrow keys are pressed.

#D Calculate the player's forward direction using cross product of the target's right direction.

#E Add together the input in each direction to become the combined motion vector.

#F LookRotation() calculates a quaternion facing in that direction.

The code in this listing starts with a serialized variable for target, because this script needs a reference to the object information technology'll motility relative to. Then we become to the Update() role. The first line of the office declares a Vector3 value of 0, 0, 0. The remaining code will supercede this vector if the player is pressing whatever buttons, but information technology's of import to accept a default value in case there isn't whatever input.

Side by side, check the input controls, just as y'all have in previous scripts. Here'south where X and Z values are set in the motion vector, for horizontal movement around the scene. Call back that Input.GetAxis() returns 0 if no button is pressed, and it varies between one and –ane when those keys are beingness pressed; putting that value in the movement vector sets the movement to the positive or negative direction of that axis (the X-axis is left-correct, and the Z-centrality is frontwards-backward).

The next several lines calculate the photographic camera-relative motility vector. Specifically, nosotros need to determine the sideways and forrad directions to move in. The sideways management is easy; the target transform has a property called correct, and that will point to the photographic camera'southward right because the camera was set as the target object. The forward direction is trickier, because the photographic camera is angled forward and down into the ground, simply we want the character to move around perpendicular to the basis. This forward direction tin can be determined using the cross production.

DEFINITION The cross product is one kind of mathematical operation that can exist done on two vectors. Long story short, the cantankerous product of 2 vectors is a new vector pointed perpendicular to both input vectors. Call back nearly the 3D coordinate axes: the Z centrality is perpendicular to both the Ten and Y axes. Don't misfile cross production with dot production; the dot product (explained later in the chapter) is a different just also commonly seen vector math performance.

In this case, the ii input vectors are the right and up directions. Remember that we already determined the photographic camera's right. Meanwhile, Vector3 has several shortcut properties for common directions, including the direction pointed straight up from the ground. The vector perpendicular to both of those points in the direction the camera faces, but aligned perpendicular to the ground.

Add the inputs in each direction to get the combined move vector. The final line of code applies that movement management to the graphic symbol by converting the Vector3 into a Quaternion using Quaternion.LookRotation() and assigning that value. Try running the game now to see what happens!

Smoothly rotating (interpolating) past using Lerp

   public bladder rotSpeed = 15.0f;          
         ...        Quaternion direction = Quaternion.LookRotation(movement);        transform.rotation = Quaternion.Lerp(transform.rotation,            direction, rotSpeed * Time.deltaTime);      }    }  }          

Currently, the character is rotating in place without moving; in the next department, you'll add lawmaking for moving the character around.

Moving forrad in that direction

In order to move the player around the scene, you demand to add together a graphic symbol controller component to the histrion object. Select the actor and then cull Component > Physics > Character Controller. In the Inspector, yous should slightly reduce the controller's radius to .4, but otherwise the default settings are all fine for this character model.

Here'southward what you need to add in the RelativeMovement script.

List ii. Adding lawmaking to change the player'southward position

    using System.Collections;  using System.Collections.Generic;  using UnityEngine;     [RequireComponent(typeof(CharacterController))]                    #A  public grade RelativeMovement : MonoBehaviour {  ...  public float moveSpeed = 6.0f;     private CharacterController charController;     void Showtime() {      charController = GetComponent<CharacterController>();          #B  }         void Update() {          ...            movement = (right * horInput) + (forward * vertInput);            movement *= moveSpeed;                                   #C            motion = Vector3.ClampMagnitude(movement, moveSpeed);  #D            ...          }             motion *= Time.deltaTime;                                #E          charController.Move(movement);      }  }        

#A The surrounding lines are context for placing the RequireComponent() method.

#B A pattern you've seen in previous chapters, used for getting admission to other components.

#C The facing directions are magnitude ane, so multiply with the desired speed value.

#D Limit diagonal movement to the aforementioned speed as movement forth an axis.

#E Always multiply movements by deltaTime to make them frame-rate contained.

If you play the game now, you volition see the graphic symbol (stuck in a T-pose) moving effectually in the scene. Pretty much the entirety of this listing is code y'all've already seen, so I'll review everything briefly.

Offset, there'due south a RequireComponent() method at the top of the lawmaking. RequireComponent() volition force Unity to make sure the GameObject has a component of the type passed into the command. This line is optional; you don't take to crave it, but without this component the script volition have errors.

Next there's a movement value alleged, followed past getting this script a reference to the character controller. Every bit you'll think from previous chapters, GetComponent() returns other components attached to the given object, and if the object to search on isn't explicitly defined, then it's assumed to be this.gameObject.GetComponent() (that is, the aforementioned object equally this script).

Motility values are still assigned based on the input controls, but now you also account for the move speed. Multiply all motility axes by the move speed, then employ Vector3.ClampMagnitude() to limit the vector'southward magnitude to the move speed; the clamp is needed because, otherwise, diagonal movement would have a greater magnitude than movement directly along an axis (movie the sides and hypotenuse of a right triangle).

Finally, at the end, you multiply the movement values by deltaTime in society to get frame charge per unit–independent movement (recall that frame charge per unit-independent ways the character moves at the same speed on different computers with different frame rates). Laissez passer the movement values to CharacterController.Move() to make the movement.

This handles all the horizontal movement; if yous want to see more than, like vertical move, check out the book here.