# Move a player About 15 minutes. ## Learning objectives - Build a plane and a cube named `Player` - Add a complete `PlayerMover` script that reads `Player/Move` - Confirm the cube moves on XZ in Play mode with WASD or arrows This page uses project-wide actions (`InputSystem.actions.FindAction`). That is the required first workflow. The [Player Input component](06-player-input-component.md) page is optional and separate. ## 1. Add a ground plane 1. In the Hierarchy, open **GameObject > 3D Object > Plane**. You should see: a Plane at the origin in the Scene view. Leave its transform at `(0, 0, 0)`. ## 2. Add a Player cube 1. In the Hierarchy, open **GameObject > 3D Object > Cube**. 2. With the Cube selected, in the Inspector rename it to `Player`. 3. Set **Transform > Position** to `X = 0`, `Y = 0.5`, `Z = 0`. You should see: the cube sitting on the plane, not intersecting it. A default cube is 1 unit tall, so `Y = 0.5` puts the bottom on `Y = 0`. ![Hierarchy with Plane and Player cube](images/05-player-hierarchy.png) ## 3. Create a Scripts folder 1. In the Project window, select the `Assets` folder. 2. Right-click > **Create > Folder**. 3. Name the folder `Scripts`. ## 4. Create PlayerMover 1. Select `Assets/Scripts`. 2. Right-click > **Create > MonoBehaviour Script** (or **Create > C# Script**). 3. Name it `PlayerMover`. The filename must match the class name. 4. Double-click `PlayerMover` to open it in your editor. 5. Replace the entire file with this script: ```csharp using UnityEngine; using UnityEngine.InputSystem; public class PlayerMover : MonoBehaviour { [SerializeField] float moveSpeed = 5f; InputAction moveAction; void Start() { moveAction = InputSystem.actions.FindAction("Player/Move"); } void Update() { if (moveAction == null) return; Vector2 move = moveAction.ReadValue<Vector2>(); Vector3 delta = new Vector3(move.x, 0f, move.y) * moveSpeed * Time.deltaTime; transform.Translate(delta, Space.World); } } ``` 6. Save the file. 7. Return to Unity and wait for compile. You should see: the Console has no compile errors. If you get `CS0246` for `InputAction`, you missed `using UnityEngine.InputSystem;` — see [Troubleshooting](07-troubleshooting.md). > **Why this matters:** `FindAction("Player/Move")` is the full path. `"Move"` alone can collide if another map also has a Move action. `move.x` is world X. `move.y` (the Vector2 Y) is world Z, so the cube stays on the plane. ## 5. Add the component to Player 1. Select `Player` in the Hierarchy. 2. In the Inspector, select **Add Component**. 3. Choose **Player Mover**. You should see: a **Player Mover** component on Player with **Move Speed** set to `5`. Do not add **Player Input** on this page. That is the next, optional workflow. ## 6. Frame the cube and check the camera 1. Select `Player` in the Hierarchy. 2. Move the mouse over the Scene view and press **F** to frame the cube. 3. Select **Main Camera**. 4. If the Game view does not show the cube on the plane, adjust the camera so both are visible (a common starter pose is position `(0, 3, -6)` looking toward the origin). ## 7. Enter Play mode Edit mode does not run `Update` on your objects in a way that moves the cube for this test. You must enter Play mode. 1. Press the **Play** button at the top of the Editor (or Ctrl/Cmd+P). 2. Click the Game view so it has focus (the Editor does not send keystrokes to the game if a different window is focused). 3. Hold **W**, **A**, **S**, **D** or the arrow keys. You should see: the cube slides on the plane. W/Up moves along +Z, S/Down along -Z, A/Left along -X, D/Right along +X. ![Play mode with the cube offset from center](images/05-play-mode-cube.png) 4. Press **Play** again to stop. > **Warning:** Changes you make in Play mode (moving the cube by hand, changing `moveSpeed`) are discarded when you stop. Set values in Edit mode. If the cube does not move, open [Troubleshooting](07-troubleshooting.md) before you continue. ## 8. Optional: gamepad 1. Plug in a USB or Bluetooth gamepad that the OS already sees. 2. Enter Play mode. 3. Tilt the left stick. You should see: the cube moves the same way as WASD. No script change is required because **Move** already has a stick binding. ## Checkpoint Before you continue: - `Player` is a cube at `Y = 0.5` on a Plane - `PlayerMover` is on `Player` and compiles - In Play mode, WASD or arrows move the cube on XZ - You are **not** calling `Input.GetAxis` or `Input.GetKey` Next (optional): [Player Input component](06-player-input-component.md). If something failed: [Troubleshooting](07-troubleshooting.md).