Many of the 3D recipes in this chapter are built on this basic project, which constructs a scene with a textured terrain, a Main Camera, and a red cube that can be moved around by the user with the four directional arrow keys. The bounds of movement of the cube are constrained using the same technique as in the previous 2D recipe.
To create a basic 3D cube controlled game, follow these steps:
SandAlbedo
(it was named GoodDirt
in Unity 4). Choose menu: Assets | Import Package | Environments, deselect everything, and then locate and tick the asset: Assets/Environment/TerrainAssets/SurfaceTextures/ SandAlbedo.psd
.You could have just added the Environment Asset Package when creating the project—but this would have imported 100s of files, and we only needed this one. Starting a project in Unity, then selectively importing just what we need is the best approach to take, if you want to keep the project's Asset folders to small sizes.
The transform position for the terrains relates to their corner and not their center.
Since the Transform position of the terrains relates to the corner of the object, we center such objects at (0,0,0) by setting the X-coordinate equal to ( -1*width/2), and the Z-coordinate equal to (-1*length/2). In other words, we slide the object by half its width and half its height to ensure that its center is just where we want it.
In this case, the width is 30 and the length is 20, hence we get -15 for X (-1 * 30/2), and -10 for Z (-1 * 20/2).
SandAlbedo
.PlayerControl
to the Cube-player:using UnityEngine; using System.Collections; public class PlayerControl : MonoBehaviour { public Transform corner_max; public Transform corner_min; public float speed = 40; private Rigidbody rigidBody; private float x_min; private float x_max; private float z_min; private float z_max; void Awake (){ rigidBody = GetComponent<Rigidbody>(); x_max = corner_max.position.x; x_min = corner_min.position.x; z_max = corner_max.position.z; z_min = corner_min.position.z; } void FixedUpdate() { KeyboardMovement(); KeepWithinMinMaxRectangle(); } private void KeyboardMovement (){ float xMove = Input.GetAxis("Horizontal") * speed * Time.deltaTime; float zMove = Input.GetAxis("Vertical") * speed * Time.deltaTime; float xSpeed = xMove * speed; float zSpeed = zMove * speed; Vector3 newVelocity = new Vector3(xSpeed, 0, zSpeed); rigidBody.velocity = newVelocity; // restrict player movement KeepWithinMinMaxRectangle (); } private void KeepWithinMinMaxRectangle (){ float x = transform.position.x; float y = transform.position.y; float z = transform.position.z; float clampedX = Mathf.Clamp(x, x_min, x_max); float clampedZ = Mathf.Clamp(z, z_min, z_max); transform.position = new Vector3(clampedX, y, clampedZ); } void OnDrawGizmos (){ Vector3 top_right = Vector3.zero; Vector3 bottom_right = Vector3.zero; Vector3 bottom_left = Vector3.zero; Vector3 top_left = Vector3.zero; if(corner_max && corner_min){ top_right = corner_max.position; bottom_left = corner_min.position; bottom_right = top_right; bottom_right.z = bottom_left.z; top_left = bottom_left; top_left.z = top_right.z; } //Set the following gizmo colors to YELLOW Gizmos.color = Color.yellow; //Draw 4 lines making a rectangle Gizmos.DrawLine(top_right, bottom_right); Gizmos.DrawLine(bottom_right, bottom_left); Gizmos.DrawLine(bottom_left, top_left); Gizmos.DrawLine(top_left, top_right); } }
corner_max
and corner_min
in the Inspector panel.The scene contains a positioned terrain so that its center is (0,0,0)
. The red cube is controlled by the user's arrow keys through the PlayerControl
script.
Just as with the previous 2D recipe, a reference to the (3D) RigidBody component is stored when the Awake()
method executes, and the maximum and minimum X- and Z- values are retrieved from the two corner GameObjects, and is stored in the x_min
, x_max
, z_min
, and z_max
variables. Note that for this basic 3D game, we won't allow any Y-movement, although such movement (and bounding limits by adding a third 'max-height' corner GameObject) can be easily added by extending the code in this recipe.
The KeyboardMovement() m
ethod reads the horizontal and vertical input values (which the Unity default settings read from the four directional arrow keys). Based on these left-right and up-down values, the velocity of the cube is updated. The amount it will move depends on the speed variable.
The KeepWithinMinMaxRectangle()
method uses the Math.Clamp(…)
function to move the character back inside the X and Z limits, so that the player's character is not permitted to move outside the area defined by the corner_max and corner_min GameObjects.
The OnDrawGizmos()
method tests that the references to the corner_max and corner_min GameObjects are not null, and then sets the positions of the four Vector3 objects, representing the four corners defined by the rectangle with the corner_max and corner_min GameObjects at the opposite corners. It then sets the Gizmo color to yellow, and draws lines connecting the four corners in the Scene panel.
3.21.93.245