I created a new Unity project and installed the package for the new Input system. Basically I just want to store the position of a click (desktop) / tap (mobile), that's it.
I know the old system provides solutions
but I want to solve it with the new input system.
I started with this input map configuration (I will show the configuration for each selected item)
I created a new script logging each click/tap position
public class FooBar : MonoBehaviour
{
public void Select(InputAction.CallbackContext context)
{
Vector2 selectPosition = context.ReadValue<Vector2>();
Debug.Log($"Select position is: {selectPosition.x}|{selectPosition.y}");
}
}
In the scene I created an empty gameobject and configured it in the inspector
Unfortunately when running the playmode I get these errors each time when moving the mouse around
This is the stacktrace of the first error message
and this is the stacktrace of the second error message
So I'm assuming my input map configuration is wrong.
Would someone mind helping me setting up an input configuration passing the click/tap position to the script?
So for a quick workaround I currently use this code with the old input system but I really don't like it ;)
public sealed class SelectedPositionStateController : MonoBehaviour
{
private void Update()
{
#if UNITY_ANDROID || UNITY_IOS
if (UnityEngine.Input.touchCount > 0)
{
Touch touch = UnityEngine.Input.GetTouch(0);
// do things with touch.position
}
#elif UNITY_STANDALONE
if (UnityEngine.Input.GetMouseButtonDown(0))
{
// do things with Input.mousePosition
}
#endif
}
// !!! USE THIS CODE BECAUSE IT'S OBVIOUSLY BETTER !!!
//
// public void SelectPosition(InputAction.CallbackContext context)
// {
// Vector2 selectedPosition = context.ReadValue<Vector2>();
//
// // do things with selectedPosition
// }
}
Add the Multi-Touch Display component to MultiTouch and drag the UI text object into the Multi Touch Info Display slot. 8. Build and run your project on your physical or emulated Android device. Using as many fingers as you can, experiment with mixing the order in which you touch and lift fingers.
In Unity, getting the mouse position on the screen is fairly straightforward. It's a property of the Input class so, to access it from a script, all you need to do is use Input. mousePosition, which returns the position of the mouse, in pixels, from the bottom left of the screen.
To achieve the desired outcome you will need 2 InputAction. One for the Click, and another for the Position.
Your MonoBehaviour
will listen to the performed
event of InputAction
related to the Click and read the Position from the one related to Position.
The InputAction
related to Position is optional; as you may catch it with the input system API.
Touchscreen.current.primaryTouch.position.ReadValue()
Mouse.current.position.ReadValue()
For your use case I suggest either:
InputAction
directly in the MonoBehaviour
InputAction
from thereSetup one InputAction
for the Click, and another for the Position.
Then you might listen to the Click and catch the position from the Position.
public class InputWithAction : MonoBehaviour
{
// --------------- FIELDS AND PROPERTIES --------------- //
[SerializeField] private InputAction _click;
[SerializeField] private InputAction _pos;
// --------------- INITIALIZATION --------------- //
private void Process(InputAction.CallbackContext callback)
{
//get the value from the position
Debug.Log($"Input action: {_pos.ReadValue<Vector2>()}");
//use the items below if you want to get the input directly
#if UNITY_ANDROID || UNITY_IOS
//gets the primary touch position using the new input system
Debug.Log(Touchscreen.current.primaryTouch.position.ReadValue());
#elif UNITY_STANDALONE
//gets the current mouse position using the new input system
Debug.Log(Mouse.current.position.ReadValue());
#endif
}
// --------------- LISTENER SETUP --------------- //
private void OnEnable()
{
_click.Enable();
_pos.Enable();
_click.performed += Process;
}
private void OnDisable()
{
_click.performed -= Process;
_click.Disable();
_pos.Disable();
}
}
The Click action requires 2 bindings.
The Position requires 2 bindings.
Your component will look like this:
Create the InputMapAsset
.
From the Editor: Assets -> Create -> InputActions. Call it "YourMap"
Remove all the actions and then add 2 actions.
A. "Click" action
Action Type: Button
Binding Mouse => Mouse/LeftButton
Binding TouchScreen => TouchScreen/Primary Touch/Tap
B. "Position" action
Action Type: Value
Binding Mouse => Mouse/Position
Binding TouchScreen => TouchScreen/Primary Touch/Position
It will look like this:
You can reference "YourMap" as InputActionAsset
as a field of your MonoBehaviour
and catch the InputAction
with the FindAction method, using the string names ("Click" and "Position").
public class InputWithMap : MonoBehaviour
{
// --------------- FIELDS AND PROPERTIES --------------- //
[SerializeField] private InputActionAsset _inputMap;
private InputAction _click;
private InputAction _pos;
private void Start()
{
//enable is required only if you're not using PlayerInput anywhere else
_inputMap.Enable();
_click = _inputMap.FindAction("Click");
_pos = _inputMap.FindAction("Position");
//listen from clicks
_click.performed += Process;
}
// --------------- INITIALIZATION --------------- //
private void Process(InputAction.CallbackContext callback)
{
//get the value from the position
Debug.Log($"Input action: {_pos.ReadValue<Vector2>()}");
}
private void OnDestroy() { _click.performed -= Process; }
}
InputAction
for the Touch Screen using ReadOnlyArray<TouchControl>
from TouchScreen class, but in that case Mouse and Touch would have a different setup. Read more for Mouse and Touch support.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With