2.5 Scripting Interactivity - Mouse and Keyboard Input in Unity
2.5 Scripting Interactivity - Mouse and Keyboard Input in Unity
2
Unity Input System Overview
The Input System allows your users to control your game or app using a
device, touch, or gestures
The Unity Input System is a modern and flexible system for handling input
in Unity games and applications. It is designed to replace the legacy Input
Manager and offers several advantages, including improved performance,
flexibility, and support for a wide range of input devices
The Input System is more extensible and provides a unified API for
various input sources, making it easier to work with different platforms and
devices
3
Input System Concepts
Basic concepts: These basic concepts and terms refer to the steps in the
sequence of events that occur when a user sends input to your game or app.
The Input System provides features which implement these steps, or you can
choose to implement some of them yourself.
4
Input System Concepts
5
Input System Concepts
6
Input System Concepts
Extended concepts: These concepts relate to more advanced handling of input,
and aren't necessary to understand straight away if you are implementing simple
input, or learning about the system for the first time.
7
Input System Workflows
There are multiple ways to use the Input System, and the workflow
that’s right for you depends on:
How quickly you want to get up and running
How flexible you want your input code to be
Whether you prefer to set things up in the Unity Editor, or in code
4 main workflows:
Directly Reading Device States
Using Embedded Actions
Using an Actions Asset
Using an Actions Asset and a PlayerInput component
8
Input System Workflows
Directly Reading Device States:
This is the simplest and most direct workflow, but the least flexible
It’s useful if you want a quick implementation with one type of device. It might not
be the best choice if you want to provide your users with multiple types of input or
if you want to target multiple platforms
9
Input System Workflows
Directly Reading Device States:
You can directly read the values from
connected devices by referring to the
device’s controls and reading the values
they are currently generating, using code
like this.
10
Input System Workflows
Directly Reading Device States:
This is often the fastest way to set up some code which responds to input, but it
is the least flexible because there is no abstraction between your code and the
values generated by a specific device
If you choose to use this technique:
You won’t benefit from Unity’s management of actions and interactions
It is harder to make your game or app work with multiple types of input device
Your input bindings are hard-coded in your script, so any changes to bindings
require changes to the code
It is harder to allow the user to remap their own controls to different actions at
run time
11
Input System Workflows
Using Embedded Actions:
You can use the InputAction class in your script to define actions in your script.
This adds a layer of abstraction between your actual action code or methods, and
the bindings to specific device controls
You do not specify explicitly which controls (such as a gamepad trigger or stick)
should do what in your code. Instead you create Actions, bind them to controls,
and respond to the states or values from your Actions in your code
12
Input System Workflows
Using Embedded Actions:
When you make a public InputAction field in a MonoBehaviour script, it displays in
the inspector as a configurable field. The configurable field UI allows you to create a
binding for the action. For example, here are two Actions defined using the
InputAction class in a script:
Window > Package Manager > Unity Registry > Search InputSystem > Install
13
Input System Workflows
Using Embedded Actions:
In the image below, you can see the
actions displayed in the inspector. In
this example they have been
configured so they are bound to
Gamepad controls.
The InputAction class allows you to link
device controls to named actions in the
inspector, enabling flexible script design
without hardcoded device references.
14
Input System Workflows
Using Embedded Actions:
By enabling actions, you can
read values through polling in
your game loop or by adding
event handlers, and disable
actions when input-triggered
event handling is no longer
needed.
This abstraction layer
facilitates easy modification or
addition of multiple bindings
without code changes.
15
Input System Workflows
Using Embedded Actions:
16
Input System Workflows
Using Embedded Actions:
• Using InputActions also makes it easier to implement a system to allow the user
to remap their own controls at run time
• Using embedded actions like this is more flexible than directly reading device
states, but less flexible than using an actions asset
17
Input System Workflows
Using Actions Asset:
The Actions Asset provides a way to define, group, and manage sets of actions as data
stored in an asset, instead of defining them directly in your code
Using an Actions Asset allows you to keep the data that defines your actions separate
from the GameObjects which should respond to the actions. This provides a further
level of abstraction and organization, compared with embedding action definitions
directly in your code
18
Input System Workflows
Using Actions Asset:
The Actions Asset is useful because it means all your action definitions are
stored as a single asset file, separate from your scripts and prefabs. This can
make it simpler to manage conceptually, and can help in practical situations
where different people in your team might work on different parts of the project at
the same time
Action Assets also provide other benefits over embedded actions in scripts, such
as the ability to group actions into Action Maps and Control Schemes
19
Input System Workflows
Using Actions Asset:
Action Maps are a way to group related actions together, where each map
relates to a different situation
For example, your game might involve driving vehicles and navigating on foot,
and may have in-game menus
In this example, it would make sense to have three different action maps for
each of these three situations, and your game code would switch between
them as appropriate
The actions grouped into the "driving" action map might be called "steer",
"accelerate", "brake", "handbrake", etc, whereas the actions grouped into the
"on foot" action map might be "move", "jump", "crouch", "use", etc
20
Input System Workflows
Using Actions Asset:
The Control Schemes, also defined in an Action Asset, allows you to specify
which bindings belong to the control schemes you define
You might have one control scheme which is "Joypad", and another control
scheme which is "Keyboard and Mouse". This allows you to determine which
control scheme the user is currently using, so your game can respond to the
user accordingly. This feature is often used to adapt the in-game UI to show the
correct keys or buttons in on-screen prompts
21
Input System Workflows
Using Actions Asset:
Right-click in the Project window or go to Assets > Create > Input Actions
22
Input System Workflows
Using Actions Asset:
When utilizing an Actions Asset, there are two ways to access it in your code:
through an inspector reference
by generating a C# class that serves as a wrapper for the Actions Asset
The choice determines how you interact with actions in your code
With an inspector reference, actions are accessed by name using strings
Alternatively, using the Generate C# class feature creates a new .cs script
asset that acts as a wrapper, allowing direct usage of API members named
after your configured actions
23
Input System Workflows
Using Actions Asset:
Referencing the Actions Asset in the inspector:
To use your Actions Asset through an inspector reference:
1. Create a public InputActionsAsset field in your script
2. Assign the reference in the inspector
3. Access the Actions in your script by name, using strings
24
Input System Workflows
Using Actions Asset:
25
Input System Workflows
Using Actions Asset:
26
Input System Workflows
Using Actions Asset:
Note: In the example above the reference to the "move" action is stored in a
variable after it is found, to avoid accessing it by string every frame, which would be
bad for performance.
27
Input System Workflows
Using Actions Asset:
Referencing the Actions Asset through a C# wrapper
• To use your Actions Asset through a C# wrapper:
1. Select your Actions Asset in the project window
2. In the Inspector, enable Generate C# Class and select Apply. You should
see a C# asset with the same name as your Actions Asset in your project
window
3. Create an instance of your Actions C# class in your script
4. Access the Actions in your script by using the API of your Actions C# class
28
Input System Workflows
Using Actions Asset:
Referencing the Actions Asset through a C# wrapper
29
Input System Workflows
Using Actions Asset:
Referencing the Actions Asset through a C# wrapper
30
Input System Workflows
Using Actions Asset:
Referencing the Actions Asset through a C# wrapper
31
Input System Workflows
Using Actions Asset:
Referencing the Actions Asset through a C# wrapper
Whether you opt for the C# wrapper or inspector reference, using an Action Asset
allows organized editing in the Actions Window. It offers flexibility compared to
embedded actions and direct device state reading, making it a versatile solution
for projects. For added abstraction, the Player Input component can be utilized to
set up method calls based on Action definitions.
32
Input System Workflows
Using an Actions Asset and a PlayerInput component:
The highest abstraction level in the Input System involves using the Actions Asset
and Player Input component together
Player Input connects Actions from the asset to C# methods in your
MonoBehaviour scripts, enabling the calling of these methods on user input
The component facilitates connection setup through an inspector UI, eliminating
the need to write code for these connections and providing flexibility in method
invocation
33
Input System Workflows
Using an Actions Asset and
a PlayerInput component:
You would typically add the
PlayerInput component to the
same GameObject as your own
MonoBehaviour script which
contains the methods that should
handle the response to the
actions
34
Input System Workflows
Using an Actions Asset and a PlayerInput component:
An example of the script which would provide an implementation of these
methods
35
Input System Workflows
Using an Actions Asset and a PlayerInput component:
36
Input System Workflows
Using an Actions Asset and a PlayerInput component:
Compared to the previous workflow, this method involves less code by
eliminating the need to reference the Actions Asset or set up event handler
methods in your script. However, it requires more setup in the Editor and might
complicate debugging due to non-hard-coded connections between actions and
code
The trade-off involves flexibility, simplicity, and implementation speed
Player Input allows connecting any action to a public method without code,
facilitating modifications without altering code. While requiring less code, coding
connections in your script may be simpler and faster than managing them in a
Player Input component on a GameObject
37
Mouse Input
Mouse input can include various actions such as button clicks, movement, and
scrolling.
This part cover handling these actions using Unity's Input System.
1. Setting Up Input Actions:
Open the Unity Editor and create a new Input Action asset or use an existing
one
Define input actions for mouse clicks, movement, and scrolling
actions = new InputActionAsset();
actions.AddAction("LeftClick", binding: "<Mouse>/leftButton");
actions.AddAction("RightClick", binding: "<Mouse>/rightButton");
actions.AddAction("MousePosition", binding: "<Mouse>/position");
actions.AddAction("ScrollWheel", binding: "<Mouse>/scroll"); 38
Mouse Input
2. Associating Input Actions with Script:
Create a C# script and associate it with a GameObject
Use the PlayerInput component to associate the script with the Input Actions
39
Mouse Input
40
Mouse Input
41
Mouse Input
3. Handling Mouse Movement:
You can use the OnMousePosition method to track the mouse position. This is useful
for tasks like aiming in a first-person shooter
4. Handling Mouse Dragging:
To implement dragging, you can use a combination of OnMousePosition and mouse
button actions
Store the initial position on a button press and calculate the delta during the drag
5. Handling Mouse Click and Hold:
Combine OnLeftClick and OnMousePosition to perform actions when the left mouse
button is clicked and held
6. Customizing Mouse Input:
• Adjust sensitivity, invert controls, or add dead zones by modifying the Input Actions
and associated methods 42
Mouse Input
7. Implementing Custom Cursors:
Change the mouse cursor appearance based on the game state or interaction
8. Using Raycasting for Interaction:
For 3D games, use raycasting from the mouse position to interact with objects
in the world
9. Handling Mouse Input in UI:
Unity's UI system has specific methods for handling mouse input on UI
elements
10. Performance Considerations:
Be mindful of performance when handling mouse input in the Update method.
Consider using InputAction events for more optimized handling
43
Mouse Input
11. Testing and Debugging:
• Test mouse input on different platforms and devices
• Utilize Unity's debugging tools to visualize input events
44
using UnityEngine;
using UnityEngine.InputSystem;
Mouse Input public class MouseClickExample : MonoBehaviour
{
Example 1:
private void OnEnable()
Detecting Left {
Mouse Click // Enable the PlayerInput component
GetComponent<PlayerInput>().enabled = true;
}
private void OnDisable()
{
// Disable the PlayerInput component
GetComponent<PlayerInput>().enabled = false;
}
private void OnLeftClick(InputAction.CallbackContext context)
{
if (context.performed)
{
Debug.Log("Left mouse button clicked!");
}
} 45
using UnityEngine;
Mouse Input using UnityEngine.InputSystem;
public class MousePositionExample : MonoBehaviour
• Example 2: {
Tracking private void OnEnable()
{
Mouse
// Enable the PlayerInput component
Position GetComponent<PlayerInput>().enabled = true;
}
private void OnDisable()
{
// Disable the PlayerInput component
GetComponent<PlayerInput>().enabled = false;
}
private void OnMousePosition(InputAction.CallbackContext context)
{
Vector2 mousePosition = context.ReadValue<Vector2>();
Debug.Log($"Mouse Position: {mousePosition}");
}
46
Mouse Input using UnityEngine;
using UnityEngine.InputSystem;
Example 3: public class MouseDraggingExample : MonoBehaviour
Mouse {
Dragging private bool isDragging = false;
private Vector2 initialMousePosition;
private void OnEnable()
{
// Enable the PlayerInput component
GetComponent<PlayerInput>().enabled = true;
}
private void OnDisable()
{
// Disable the PlayerInput component
GetComponent<PlayerInput>().enabled = false;
}
}
47
private void OnLeftClick(InputAction.CallbackContext context)
Mouse Input {
if (context.performed)
Example 3: {
Mouse isDragging = true;
Dragging initialMousePosition = Mouse.current.position.ReadValue();
}
else if (context.canceled)
isDragging = false;
}
private void OnMousePosition(InputAction.CallbackContext context)
{
if (isDragging)
{
Vector2 currentMousePosition = context.ReadValue<Vector2>();
Vector2 dragDelta = currentMousePosition - initialMousePosition;
// Use dragDelta for dragging logic
Debug.Log($"Mouse Drag Delta: {dragDelta}");
} 48
Keyboard Input
Scripting for keyboard input in Unity involves using the Unity Input System to detect
and respond to key presses, releases, and other keyboard-related events. The
Unity Input System provides a flexible and unified way to handle various input
devices, including keyboards.
An overview of scripting for keyboard input in Unity:
1. Enabling the Input System:
Ensure that the Unity Input System package is installed in your project. You can do
this using the Unity Package Manager
2. Creating Input Actions:
Open the Unity Editor and navigate to "Window" > "Input Actions" to create a new
Input Actions asset
Define input actions for keyboard events such as key presses, releases, and
combinations 49
Keyboard Input
3. Associating Input Actions with Scripts:
Create a C# script that will handle the keyboard input
Use the PlayerInput component to associate the script with the Input Actions
4. Defining Callback Methods:
Define methods in your script to handle specific keyboard events. These
methods will be triggered when the associated input actions occur
Callback methods often start with "On" followed by the type of event (e.g.,
OnKeyPress, OnKeyRelease)
5. Reading Input Values:
Use the context.ReadValue method to read input values in your callback
methods
For key presses, you might use context.performed. For key releases, you
might use context.canceled
50
Keyboard Input
6. Handling Specific Keys:
To handle specific keys, you can check the name of the input action in your
callback methods
For example, to handle the "W" key: if (context.action.name == "W")
7. Handling Key Combinations:
You can set up input actions for key combinations and respond to them in your
callback methods
For example, a combination of "Ctrl" + "C" can be handled by checking both
keys in your method
8. Managing Key Holding:
Use the context.performed and context.canceled checks to determine when a
key is held down or released
For continuous actions, use context.started and context.performed
51
Keyboard Input
9. Testing and Debugging:
• Test your keyboard input scripts in the Unity Editor and ensure they respond
as expected
• Use Debug.Log statements to print information during testing
52
using UnityEngine;
using UnityEngine.InputSystem;
Keyboard Input public class KeyPressExample : MonoBehaviour
{
Example 1: private void OnEnable()
Simple Key {
// Enable the PlayerInput component
Press GetComponent<PlayerInput>().enabled = true;
}
private void OnDisable()
{
// Disable the PlayerInput component
GetComponent<PlayerInput>().enabled = false;
}
private void OnKeyPress(InputAction.CallbackContext context)
{
if (context.performed)
{
Debug.Log("Key pressed!");
}
} 53
using UnityEngine;
Keyboard Input
using UnityEngine.InputSystem;
Example 2: public class SpecificKeyPressExample :
Specific Key Press MonoBehaviour
{
private void OnEnable()
{
// Enable the PlayerInput component
GetComponent<PlayerInput>().enabled = true;
}
private void OnDisable()
{
// Disable the PlayerInput component
GetComponent<PlayerInput>().enabled = false;
}
54
Keyboard Input
Example 2: private void OnSpecificKeyPress(InputAction.CallbackContext context)
Specific {
Key Press if (context.performed && context.ReadValue<float>() > 0.5f)
{
// Check for a specific key (e.g., W key)
if (context.action.name == "W")
{
Debug.Log("W key pressed!");
}
}
}
}
55
using UnityEngine;
Keyboard Input using UnityEngine.InputSystem;
public class KeyReleaseExample : MonoBehaviour
{
Example 3:
private void OnEnable()
Key Release {
// Enable the PlayerInput component
GetComponent<PlayerInput>().enabled = true;
}
private void OnDisable()
{
// Disable the PlayerInput component
GetComponent<PlayerInput>().enabled = false;
}
private void OnKeyRelease(InputAction.CallbackContext context)
{
if (context.performed)
{
Debug.Log("Key released!");
}
} 56
Keyboard Input using UnityEngine;
using UnityEngine.InputSystem;
Example 4:
public class KeyHoldingExample : MonoBehaviour
Key Holding {
private bool isKeyHeld = false;