This is my first project using Unity’s new input system. Sorry if I’m misunderstanding some fundamentals 
I’m developing a mobile game in which I want to support gamepad and touch input for character movement.
I loaded up Unity’s new input system On-Screen Controls example. The OnScreenStick component uses the Right Stick [GamePad] path. The problem I have with using this path is that it sets the current control scheme to gamepad instead of touch so I can’t determine if the input has come from a gamepad or the OnScreenStick. I need to be able to process the input differently based on the current control scheme.
How do I determine if OnScreenStick input is touch input?
I usualy set to Right Stick on gamepad, work for both, touch and physical
Thanks for your reply @Fluttershy28 , but the problem is when you’re using the Right Stick [GamePad] path the current control scheme will return gamepad regardless of whether you’re using the gamepad or touchscreen.
It’s because that example simulates the look stick as a Right Stick [Gamepad] since the binding Touchscreen [Delta] lead to unexpected behaviors. I don’t know if unity intended to do it that way, because is not very objective. Basically if you add a binding of type Touchscreen [Delta] on your look action, will automatically enable the touch, you can test by enabling touch simulation on Window menu, Analysis, Input Debugger an toggle “Simulate touch input from mouse or pen” in the options drop down on the up left corner. But you’ll see that does not work for what you want at all, since the common UI elements don’t block the touch input, than when you try to use the Left Stick will also trigger the touch.
Every single tutorial on a simple FPS Mobile system in the internet uses a On Screen Stick as the look input, what is dogshit, since the right stick may work on a gamepad, but in the touchscreen lacks vital information, such as if the touch is stationary, etc. I did found a nice way to make a smooth FPS, i’ll explain how i managed that in the next answer
1 Like
Basically Instead of using a Touchscreen [Delta] which will lead on some unwanted behaviors, if you use EnhancedTouch will return a way better result. To do it you need to:
-Remove any Touchscreen [Delta] bindings on your look actions, you can leave the Right Stick, Mouse Delta.
-Make a Script to hande EnhancedTouch.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using Cinemachine;
using UnityEngine.InputSystem.EnhancedTouch;
using Touch = UnityEngine.InputSystem.EnhancedTouch.Touch;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;
public class PlayerLookManager : MonoBehaviour
{
[SerializeField] CinemachineVirtualCamera cVCam;
Vector2 lookValue;
int lookTouchId;
private void Awake()
{
EnhancedTouchSupport.Enable();
}
private void Update()
{
GetTouchInput();
}
private void GetTouchInput()
{
for (int i = 0; i < Touch.activeFingers.Count; i++)
{
Touch t = Touch.activeTouches[i];
switch (t.phase)
{
case TouchPhase.Began:
if (IsPointerOverThisUIElement())
{
lookTouchId = t.finger.index;
}
break;
case TouchPhase.Ended:
lookTouchId = -1;
lookValue = Vector2.zero;
OverrideLookAction();
break;
case TouchPhase.Canceled:
lookTouchId = -1;
lookValue = Vector2.zero;
OverrideLookAction();
break;
case TouchPhase.Moved:
if (lookTouchId != -1)
{
lookValue = t.delta;
OverrideLookAction();
}
break;
case TouchPhase.Stationary:
if (lookTouchId != -1)
{
lookValue = Vector2.zero;
OverrideLookAction();
}
break;
}
}
}
private void OverrideLookAction()
{
float verticalValue = cVCam.GetCinemachineComponent<CinemachinePOV>().m_VerticalAxis.m_InputAxisValue;
verticalValue = lookValue.y;
cVCam.GetCinemachineComponent<CinemachinePOV>().m_VerticalAxis.m_InputAxisValue = verticalValue;
float horizontalValue = cVCam.GetCinemachineComponent<CinemachinePOV>().m_HorizontalAxis.m_InputAxisValue;
horizontalValue = lookValue.x;
cVCam.GetCinemachineComponent<CinemachinePOV>().m_HorizontalAxis.m_InputAxisValue = horizontalValue;
// obs The Player body rotation will not match the camera rotation, you can do it by code
}
public bool IsPointerOverThisUIElement()
{
return IsPointerOverThisUIElement(GetEventSystemRaycastResults());
}
private bool IsPointerOverThisUIElement(List<RaycastResult> eventSystemRaysastResults)
{
for (int index = 0; index < eventSystemRaysastResults.Count; index++)
{
RaycastResult curRaysastResult = eventSystemRaysastResults[index];
if (curRaysastResult.gameObject == gameObject)
return true;
}
return false;
}
static List<RaycastResult> GetEventSystemRaycastResults()
{
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.position = Input.mousePosition;
List<RaycastResult> raysastResults = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, raysastResults);
return raysastResults;
}
}
-Create a Ui image of the size you want your touch to be, set the alpha to 0, but don’t disable it, also put the above sctipt on it.
-Set a Virtual Cinemachine Camera and switch Input provider as you change from control to touch.