# Player Input component
About 15 minutes. Optional second workflow.
## Learning objectives
- Add a **Player Input** component that uses the same actions asset
- Wire **Move** and **Jump** to Unity Events
- Implement `OnMove` and `OnJump` with `InputAction.CallbackContext`
- Choose this workflow vs `FindAction` for a given script
Use this page after [Move a player](05-move-a-player.md) works. Keep the same Plane and Player cube.
## When to use which workflow
| Workflow | How it runs | Use it when |
| --- | --- | --- |
| `InputSystem.actions.FindAction("Player/Move")` | Script looks up the project-wide action | First scripts, one player, fewer Inspector clicks |
| **Player Input** + **Invoke Unity Events** | Inspector wires each action to a public method | Designers need to hook events without editing C#; local multiplayer later |
Both read the same Action Maps. Do not run both on the same object at the same time. **Player Input** also makes a private copy of the actions for that player. Do not also read `InputSystem.actions` from that object.
This course assignment only requires the `FindAction` script. This page is extra practice.
## 1. Disable the first mover
1. Select `Player` in the Hierarchy.
2. On the **Player Mover** component, clear the enable checkbox.
You should see: **Player Mover** is still there but disabled. You can delete it instead if you prefer.
## 2. Add Player Input
1. Select `Player`.
2. In the Inspector, select **Add Component**.
3. Choose **Player Input**.
4. Set **Actions** to the project-wide asset (`InputSystem_Actions` in `Assets`, or the asset assigned under **Edit > Project Settings > Input System Package**).
5. Set **Default Map** to **Player**.
6. Set **Behavior** to **Invoke Unity Events**.
You should see: an **Events** foldout on the Player Input component, with a **Player** section listing Move, Look, Jump, Attack, and the other Player actions.
## 3. Create PlayerMoverEvents
1. Select `Assets/Scripts`.
2. Right-click > **Create > MonoBehaviour Script** (or **Create > C# Script**).
3. Name it `PlayerMoverEvents`.
4. Open the file and replace it with:
```csharp
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMoverEvents : MonoBehaviour
{
[SerializeField] float moveSpeed = 5f;
Vector2 moveInput;
public void OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
}
public void OnJump(InputAction.CallbackContext context)
{
if (context.performed)
Debug.Log("Jump");
}
void Update()
{
Vector3 delta = new Vector3(moveInput.x, 0f, moveInput.y) * moveSpeed * Time.deltaTime;
transform.Translate(delta, Space.World);
}
}
```
5. Save the file and wait for Unity to compile.
> **Why this matters:** Unity Events for an action fire on **started**, **performed**, and **canceled**. `OnMove` stores the latest Vector2, including `(0, 0)` when the keys are released. `OnJump` logs only on `performed` so one press does not print three times.
The method names `OnMove` and `OnJump` are conventions. The Inspector wiring is what connects them, not the names.
## 4. Add the script and wire events
1. Select `Player`.
2. **Add Component** > **Player Mover Events**.
3. On **Player Input**, expand **Events > Player**.
4. On **Move**, select the **+**.
5. Drag the `Player` object from the Hierarchy into the object field (or drag the **Player Mover Events** component).
6. Open the function dropdown and choose **PlayerMoverEvents > OnMove (CallbackContext)**.
You should see: the Move event lists `PlayerMoverEvents.OnMove`.

7. On **Jump**, select the **+**.
8. Assign `Player` again.
9. Choose **PlayerMoverEvents > OnJump (CallbackContext)**.
If `OnMove` does not appear, the method is not `public`, or the parameter is not `InputAction.CallbackContext`. Fix the script, compile, then wire again.
## 5. Test in Play mode
1. Press **Play**.
2. Click the Game view.
3. Use WASD or arrows.
You should see: the cube moves as before.
4. Press **Space**.
You should see: the Console prints `Jump`.
5. Stop Play mode.
## Checkpoint
Before you leave this page:
- **Player Mover** is disabled or removed
- **Player Input** is on `Player`, **Default Map** is **Player**, **Behavior** is **Invoke Unity Events**
- **Move** and **Jump** events call `OnMove` and `OnJump`
- In Play mode the cube moves, and Jump logs once per press
If events do not fire, see [Troubleshooting](07-troubleshooting.md).