unity-game-agent / unity_agent /knowledge /entries /unity_input_system.md
ryzerrr's picture
Upload folder using huggingface_hub
40c0886 verified
|
Raw
History Blame Contribute Delete
5.04 kB
# Unity Input System
Unity offers two input systems:
1. **Input Manager (legacy)** -- `Input.GetAxis`, `Input.GetKeyDown`. The
default in 2022.3 LTS. Used by every generated script in this project.
2. **Input System package** -- the new event-driven API. Available via the
`com.unity.inputsystem` package.
## Input Manager (legacy)
### Axes
The legacy system reads virtual axes defined in
`Edit > Project Settings > Input Manager`. The defaults include:
| Axis name | Default keys |
|---------------|---------------------------------|
| `Horizontal` | A/D, Arrow Left/Right |
| `Vertical` | W/S, Arrow Up/Down |
| `Mouse X` | Mouse delta X |
| `Mouse Y` | Mouse delta Y |
| `Jump` | Space |
| `Fire1` | Left Ctrl / Mouse 0 |
| `Fire2` | Right Alt / Mouse 1 |
| `Fire3` | Left Shift / Mouse 2 |
### Reading axes
```csharp
float x = Input.GetAxisRaw("Horizontal"); // -1, 0, +1 (no smoothing)
float y = Input.GetAxis("Vertical"); // smoothed, -1..+1
Vector2 move = new Vector2(x, y);
move = Vector2.ClampMagnitude(move, 1f); // prevent diagonal speed boost
```
* Use `GetAxisRaw` for responsive arcade movement; `GetAxis` for smooth
camera-style axes.
* Always clamp the magnitude of a 2-axis vector -- otherwise diagonal
movement is ~1.41x faster than cardinal.
### Keys and buttons
```csharp
if (Input.GetKeyDown(KeyCode.Space)) Jump();
if (Input.GetKey(KeyCode.LeftShift)) Sprint();
if (Input.GetKeyUp(KeyCode.E)) Interact();
if (Input.GetMouseButtonDown(0)) Fire();
if (Input.GetMouseButton(0)) FireContinuous();
```
| Method | Fires when |
|-----------------------|-------------------------------------------|
| `GetKey` | Every frame the key is held |
| `GetKeyDown` | Only on the frame the key was pressed |
| `GetKeyUp` | Only on the frame the key was released |
| `GetMouseButton` | Every frame the button is held |
| `GetMouseButtonDown` | Only on the frame the button went down |
### Mouse position and delta
```csharp
Vector3 mousePos = Input.mousePosition; // screen-space pixels
float dx = Input.GetAxis("Mouse X"); // smoothed delta
float rawDx = Input.GetAxisRaw("Mouse X");
```
To lock the cursor for first-person look:
```csharp
Cursor.lockState = CursorLockMode.Locked; // hide + center
Cursor.visible = false;
```
## Mouse-look recipe (first-person)
```csharp
private float _pitch;
private void Update()
{
float mx = Input.GetAxisRaw("Mouse X") * sensitivity;
float my = Input.GetAxisRaw("Mouse Y") * sensitivity;
transform.Rotate(Vector3.up * mx);
_pitch = Mathf.Clamp(_pitch - my, -85f, 85f);
cameraTransform.localRotation = Quaternion.Euler(_pitch, 0f, 0f);
}
```
## Mouse-look recipe (third-person orbit)
For a third-person camera we accumulate a **yaw** and **pitch** and build a
rotation each frame:
```csharp
_yaw += Input.GetAxis("Mouse X") * sensitivity;
_pitch -= Input.GetAxis("Mouse Y") * sensitivity;
_pitch = Mathf.Clamp(_pitch, -30f, 75f);
Quaternion rotation = Quaternion.Euler(_pitch, _yaw, 0f);
Vector3 position = pivot + rotation * new Vector3(0f, height, -distance);
```
The `ThirdPersonCamera.cs` generator follows exactly this pattern.
## Input System package (new)
When the project has the Input System package active, the legacy `Input`
class will throw or return zeros unless `Project Settings > Player > Active Input Handling = Both`.
The new API is event-based:
```csharp
[SerializeField] private InputActionAsset actions;
private InputAction _moveAction;
private void OnEnable()
{
_moveAction = actions.FindAction("Move");
_moveAction.performed += OnMove;
_moveAction.Enable();
}
private void OnMove(InputAction.CallbackContext ctx) => _moveInput = ctx.ReadValue<Vector2>();
private void OnDisable() => _moveAction.Disable();
```
For the generated project we keep Active Input Handling on **Both** so the
legacy `Input` calls in the generated scripts keep working.
## Touch and mobile
For mobile, read `Input.touches` (legacy) or the new Input System's
`Pointer`/`Touchscreen`:
```csharp
foreach (Touch t in Input.touches)
{
if (t.phase == TouchPhase.Began) HandleTap(t.position);
}
```
The generated scripts are desktop-first; you would add a virtual joystick
overlay for mobile ports.
## Common pitfalls
* Reading `Input` in `FixedUpdate` -- the input system updates once per
frame, but `FixedUpdate` may run 0..N times per frame, so you will drop
or duplicate inputs.
* Using `Input.GetAxis` for physics forces -- the smoothed value can cause
floaty controls. Prefer `GetAxisRaw` and apply your own smoothing.
* Forgetting to lock the cursor in an FPS leads to the camera spinning
when the cursor leaves the game window.