Custom touch-screen input module

This is an experimental input module that aims to improve the behaviour of Unity UI elements with touch-screen input. If you are experiencing issues with Unity UI-based AC menus on mobile devices, give this a try.

To use it:

1. Paste the code below into a new C# script named CustomTouchInputModule.cs
2. Attach this script as a component to a new empty GameObject, and make the GameObject a prefab
3. Assign this prefab in to the AC Menu Manager's **EventSystem prefab** field.

CustomTouchInputModule.cs:

```
using UnityEngine.EventSystems;

using UnityEngine;

namespace AC

{

	public class CustomTouchInputModule : StandaloneInputModule

	{

		private bool allowMouseInput = true;

		private readonly MouseState m_MouseState = new MouseState ();

		public bool AllowMouseInput

		{

			get

			{

				return allowMouseInput;

			}

			set

			{

				allowMouseInput = value;

			}

		}

		protected void Update ()

		{

			AllowMouseInput = !CanDirectlyControlMenus ();

		}

		protected virtual bool CanDirectlyControlMenus ()

		{

			if (KickStarter.settingsManager != null && KickStarter.settingsManager.inputMethod == InputMethod.TouchScreen)

			{

				return false;

			}

				(KickStarter.stateHandler.IsInGameplay () && KickStarter.playerInput.canKeyboardControlMenusDuringGameplay))

			{

				return true;

			}

			return false;

		}

		protected override MouseState GetMousePointerEventData (int id = 0)

		{

			if (KickStarter.settingsManager == null || KickStarter.settingsManager.inputMethod == InputMethod.MouseAndKeyboard)

			{

				return base.GetMousePointerEventData (id);

			}

			if (KickStarter.settingsManager.inputMethod == InputMethod.TouchScreen)

			{

				return GetTouchEventData (id);

			}

			PointerEventData leftData;

			var created = GetPointerData (kMouseLeftId, out leftData, true);

			leftData.Reset ();

			Vector2 pos = KickStarter.playerInput.GetMousePosition ();

			if (created)

			{

				leftData.position = pos;

			}

			leftData.delta = pos - leftData.position;

			leftData.position = pos;

			leftData.scrollDelta = Input.mouseScrollDelta;

			leftData.button = PointerEventData.InputButton.Left;

			eventSystem.RaycastAll (leftData, m_RaycastResultCache);

			RaycastResult raycast = FindFirstRaycast (m_RaycastResultCache);

			leftData.pointerCurrentRaycast = raycast;

			m_RaycastResultCache.Clear ();

			if (raycast.isValid && KickStarter.menuManager.autoSelectValidRaycasts && !CanDirectlyControlMenus ())

			{

				KickStarter.playerMenus.EventSystem.SetSelectedGameObject (raycast.gameObject);

			}

			PointerEventData rightData;

			GetPointerData (kMouseRightId, out rightData, true);

			CopyFromTo (leftData, rightData);

			rightData.button = PointerEventData.InputButton.Right;

			PointerEventData middleData;

			GetPointerData (kMouseMiddleId, out middleData, true);

			CopyFromTo (leftData, middleData);

			middleData.button = PointerEventData.InputButton.Middle;

			PointerEventData.FramePressState leftClickState = PointerEventData.FramePressState.NotChanged;

			if (KickStarter.settingsManager.inputMethod == InputMethod.TouchScreen)

			{

				if (Input.touchCount == 1)

				{

					TouchPhase phase = Input.GetTouch (0).phase;

					switch (phase)

					{

						case TouchPhase.Began:

							leftClickState = PointerEventData.FramePressState.Pressed;

							break;

						case TouchPhase.Canceled:

							leftClickState = PointerEventData.FramePressState.Released;

							break;

						case TouchPhase.Ended:

							leftClickState = PointerEventData.FramePressState.PressedAndReleased;

							break;

						default:

							break;

					}

				}

			}

			else

			{

				if (KickStarter.playerInput.InputGetButtonDown ("InteractionA"))

				{

					leftClickState = PointerEventData.FramePressState.Pressed;

				}

				else if (KickStarter.playerInput.InputGetButtonUp ("InteractionA"))

				{

					leftClickState = PointerEventData.FramePressState.Released;

				}

			}

			PointerEventData.FramePressState rightClickState = PointerEventData.FramePressState.NotChanged;

			if (KickStarter.playerInput.InputGetButtonDown ("InteractionB"))

			{

				rightClickState = PointerEventData.FramePressState.Pressed;

			}

			else if (KickStarter.playerInput.InputGetButtonUp ("InteractionB"))

			{

				rightClickState = PointerEventData.FramePressState.Released;

			}

			m_MouseState.SetButtonState (PointerEventData.InputButton.Left, leftClickState, leftData);

			m_MouseState.SetButtonState (PointerEventData.InputButton.Right, rightClickState, rightData);

			m_MouseState.SetButtonState (PointerEventData.InputButton.Middle, StateForMouseButton (2), middleData);

			return m_MouseState;

		}

		private MouseState GetTouchEventData (int id)

		{

			// Populate the left button...

			PointerEventData leftData;

			var created = GetPointerData (kMouseLeftId, out leftData, true);

			leftData.Reset ();

			if (created)

				leftData.position = input.mousePosition;

			//Vector2 pos = input.mousePosition;

			Vector2 pos = KickStarter.playerInput.GetMousePosition ();

			if (Cursor.lockState == CursorLockMode.Locked)

			{

				// We don't want to do ANY cursor-based interaction when the mouse is locked

				leftData.position = new Vector2 (-1.0f, -1.0f);

				leftData.delta = Vector2.zero;

			}

			else

			{

				leftData.delta = pos - leftData.position;

				leftData.position = pos;

			}

			leftData.scrollDelta = input.mouseScrollDelta;

			leftData.button = PointerEventData.InputButton.Left;

			eventSystem.RaycastAll (leftData, m_RaycastResultCache);

			var raycast = FindFirstRaycast (m_RaycastResultCache);

			leftData.pointerCurrentRaycast = raycast;

			m_RaycastResultCache.Clear ();

			// copy the apropriate data into right and middle slots

			PointerEventData rightData;

			GetPointerData (kMouseRightId, out rightData, true);

			CopyFromTo (leftData, rightData);

			rightData.button = PointerEventData.InputButton.Right;

			PointerEventData middleData;

			GetPointerData (kMouseMiddleId, out middleData, true);

			CopyFromTo (leftData, middleData);

			middleData.button = PointerEventData.InputButton.Middle;

			m_MouseState.SetButtonState (PointerEventData.InputButton.Left, StateForMouseButton (0), leftData);

			m_MouseState.SetButtonState (PointerEventData.InputButton.Right, StateForMouseButton (1), rightData);

			m_MouseState.SetButtonState (PointerEventData.InputButton.Middle, StateForMouseButton (2), middleData);

			return m_MouseState;

		}

		public override void Process ()

		{

			bool usedEvent = SendUpdateEventToSelectedObject ();

			if (eventSystem.sendNavigationEvents)

			{

				if (!usedEvent)

				{

					usedEvent |= SendMoveEventToSelectedObject ();

				}

				if (!usedEvent)

				{

					SendSubmitEventToSelectedObject ();

				}

			}

			if (allowMouseInput)

			{

				ProcessMouseEvent ();

			}

		}

	}

}

```