Mouse Input
In this article, we'll show you how to get started with sending mouse input to Nova using both Unity's legacy Input APIs as well as Unity's new Input System Package. The exact code will depend on the input library you use, but the Nova-relevant code boils down to:
- Calling Interaction.Point with the world-space mouse ray and pressed state.
- Calling Interaction.Scroll with the world-space mouse ray and scroll delta.
See the Grid Inventory Sample for an example of mouse input in action.
See Input Overview for an overview of Nova's input system.
Legacy Input APIs
using Nova;
using UnityEngine;
public class LegacyMouseInputSample : MonoBehaviour
{
public const uint MousePointerControlID = 1;
public const uint ScrollWheelControlID = 2;
/// <summary>
/// Inverts the mouse wheel scroll direction.
/// </summary>
public bool InvertScrolling = true;
private void Update()
{
if (!Input.mousePresent)
{
// Nothing to do, no mouse device detected
return;
}
// Get the current world-space ray of the mouse
Ray mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
// Get the current scroll wheel delta
Vector2 mouseScrollDelta = Input.mouseScrollDelta;
// Check if there is any scrolling this frame
if (mouseScrollDelta != Vector2.zero)
{
// Invert scrolling for a mouse-type experience,
// otherwise will scroll track-pad style.
if (InvertScrolling)
{
mouseScrollDelta.y *= -1f;
}
// Create a new Interaction.Update from the mouse ray and scroll wheel control id
Interaction.Update scrollInteraction = new Interaction.Update(mouseRay, ScrollWheelControlID);
// Feed the scroll update and scroll delta into Nova's Interaction APIs
Interaction.Scroll(scrollInteraction, mouseScrollDelta);
}
bool leftMouseButtonDown = Input.GetMouseButton(0);
// Create a new Interaction.Update from the mouse ray and pointer control id
Interaction.Update pointInteraction = new Interaction.Update(mouseRay, MousePointerControlID);
// Feed the pointer update and pressed state to Nova's Interaction APIs
Interaction.Point(pointInteraction, leftMouseButtonDown);
}
}
Input System Package
using Nova;
using UnityEngine;
using UnityEngine.InputSystem;
public class MouseInputSample : MonoBehaviour
{
public const uint MousePointerControlID = 1;
public const uint ScrollWheelControlID = 2;
/// <summary>
/// Inverts the mouse wheel scroll direction.
/// </summary>
public bool InvertScrolling = true;
private void Update()
{
if (Mouse.current == null)
{
return;
}
// Get the mouse ray in world space
Vector2 position = Mouse.current.position.ReadValue();
Ray mouseRay = Camera.main.ScreenPointToRay(position);
Vector2 mouseScrollDelta = Mouse.current.scroll.ReadValue();
// Check if there is any scrolling this frame
if (mouseScrollDelta != Vector2.zero)
{
// Normalize the scroll delta to be more consistent with
// the legacy Input.mouseScrollDelta API
mouseScrollDelta = mouseScrollDelta.normalized;
if (InvertScrolling)
{
mouseScrollDelta.y *= -1f;
}
// Create a new Interaction.Update from the mouse ray and scroll wheel control id
Interaction.Update scrollInteraction = new Interaction.Update(mouseRay, ScrollWheelControlID);
// Feed the scroll update and scroll delta into Nova's Interaction APIs
Interaction.Scroll(scrollInteraction, mouseScrollDelta);
}
// Create a new Interaction.Update from the mouse ray and pointer control id
Interaction.Update pointInteraction = new Interaction.Update(mouseRay, MousePointerControlID);
// Feed the pointer update and pressed state to Nova's Interaction APIs
bool pressed = Mouse.current.leftButton.isPressed;
Interaction.Point(pointInteraction, pressed);
}
}
Right Clicks
There are several ways to accomplish right clicks with Nova, one of which is using the UserData field of the Interaction.Update passed into Interaction.Point (this is the approach the Grid Inventory Sample uses). For example, you could create a MouseState
type to hold the state of the mouse:
public class MouseState
{
public bool LeftPressed;
public bool RightPressed;
public bool EitherButtonPressed => LeftPressed || RightPressed;
}
Which you then provide to the constructor of Interaction.Update:
/// <summary>
/// Reuse to avoid generating garbage.
/// </summary>
private MouseState mouseState = new MouseState();
private void Update()
{
// ...
// Set the state of the mouse
mouseState.LeftPressed = Input.GetMouseButton(0);
mouseState.RightPressed = Input.GetMouseButton(1);
// Provide the mouseState instance
Interaction.Update pointInteraction = new Interaction.Update(mouseRay, MousePointerControlID, userData: mouseState);
// Call point, with the pointerDown argument being true if either the
// left or right button is pressed
Interaction.Point(pointInteraction, mouseState.EitherButtonPressed);
}
Then, in your Gesture handling code, you can check the values of the provided MouseState
and react accordingly:
private void HandleClick(Gesture.OnClick evt)
{
MouseState mouseState = evt.Interaction.UserData as MouseState;
if (mouseState.RightPressed)
{
// Perform right-click logic
}
else
{
// Perform left-click logic
}
}