Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions Runtime/MobileInput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,12 @@ public enum HardwareOrientation {
/// </summary>
public abstract class MobileInputReceiver : MonoBehaviour {

#if !UNITY_EDITOR
/// <summary>
/// Current input id
/// </summary>
int _id = 0;
#endif

/// <summary>
/// Init input and register interface
Expand Down Expand Up @@ -270,11 +272,17 @@ public void OnData(JsonObject data) {
GetReceiver(id).Send(response);
}
_data = null;
} catch (Exception e) {
}
#if UMI_DEBUG
catch (Exception e) {
Debug.LogError($"[UMI] received error: {e}");
#endif
}
#else
catch {
// Ignored
}
#endif

}

/// <summary>
Expand All @@ -301,11 +309,16 @@ void OnDataReceive(string data) {
} else {
OnData(info);
}
} catch (Exception e) {
}
#if UMI_DEBUG
catch (Exception e) {
Debug.LogError($"[UMI] raw data error: data = {data}, error = {e}");
#endif
}
#else
catch {
// Ignored
}
#endif
}

#if UNITY_ANDROID
Expand All @@ -317,7 +330,7 @@ public static bool IsRotationLocked() {
return plugin.CallStatic<bool>("checkIsRotateLocked");
}
}

/// <summary>
/// Return type of screen navigation
///
Expand All @@ -330,7 +343,7 @@ public static int GetBarType() {
using (var plugin = new AndroidJavaClass(PLUGIN_PACKAGE)) {
return plugin.CallStatic<int>("getBarType");
}
}
}

/// <summary>
/// Get height of navigation bar
Expand All @@ -340,7 +353,7 @@ public static int GetBarHeight() {
using (var plugin = new AndroidJavaClass(PLUGIN_PACKAGE)) {
return plugin.CallStatic<int>("getBarHeight");
}
}
}
#endif

/// <summary>
Expand Down
164 changes: 155 additions & 9 deletions Runtime/MobileInputField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@
using UnityEngine;
using NiceJson;
using UnityEngine.Events;
#if !UNITY_EDITOR
using System.Collections.Generic;
using System.Linq;
using LegacyTouch = UnityEngine.Touch;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.EnhancedTouch;
using InputSystemTouch = UnityEngine.InputSystem.EnhancedTouch.Touch;
#endif
#endif

namespace UMI {

Expand Down Expand Up @@ -270,6 +281,18 @@ public enum ReturnKeyType {
/// </summary>
CultureInfo _cultureInfo = CultureInfo.InvariantCulture;

#if UNITY_ANDROID && !UNITY_EDITOR && ENABLE_INPUT_SYSTEM
/// <summary>
/// Last input character from the 'current' keyboard
/// </summary>
char? _lastInputChar = null;

/// <summary>
/// The keyboard we are listening to for input strings
/// </summary>
Keyboard _boundKeyboard = null;
#endif

/// <summary>
/// Constructor
/// </summary>
Expand All @@ -282,6 +305,15 @@ void Awake() {
throw new MissingComponentException();
}
_inputObjectText = _inputObject.textComponent;

#if UMI_DEBUG && !UNITY_EDITOR
#if ENABLE_INPUT_SYSTEM
Debug.Log($"[UMI] Input type: (New) Input System");
#else
Debug.Log($"[UMI] Input type: (Legacy) Input Manager");
#endif
#endif

}

/// <summary>
Expand Down Expand Up @@ -416,11 +448,11 @@ void Update() {
#endif
if (_inputObject != null && _isMobileInputCreated) {
#if !UNITY_EDITOR
var touchCount = Input.touchCount;
if (touchCount > 0) {
var tapCount = GetTapCount();
if (tapCount > 0) {
var inputRect = this._inputObjectText.rectTransform.rect;
for (var i = 0; i < touchCount; i++) {
if (!inputRect.Contains(Input.touches[i].position)) {
for (var i = 0; i < tapCount; i++) {
if (!inputRect.Contains(GetTapPosition(i))) {
#if UMI_DEBUG
Debug.Log($"[UMI] manual hide control: {IsManualHideControl}");
#endif
Expand Down Expand Up @@ -824,21 +856,135 @@ private void ForceSendKeydownAndroid(string key) {
/// Keyboard handler
/// </summary>
private void UpdateForceKeyeventForAndroid() {
if (Input.anyKeyDown) {
if (Input.GetKeyDown(KeyCode.Backspace)) {

var inputState = GetAndroidInputState();

if (inputState.AnyKey) {
if (inputState.AndroidBack) {
if (!IsManualHideControl) {
#if UMI_DEBUG
Debug.Log("[UMI] Android back button pressed, hiding keyboard");
#endif
Hide();
}
} else if (inputState.Backspace) {
ForceSendKeydownAndroid("backspace");
} else {
foreach (var c in Input.inputString) {
foreach (var c in inputState.InputString) {
if (c == '\n') {
ForceSendKeydownAndroid("enter");
} else {
ForceSendKeydownAndroid(Input.inputString);
ForceSendKeydownAndroid(c.ToString());
}
}
}
}
}

private struct AndroidInputState {
public bool AnyKey;
public bool AndroidBack;
public bool Backspace;
public string InputString;
}

/// <summary>
/// Gets the current state of input for Android specific logic, in an input-system-agnostic way
/// </summary>
private AndroidInputState GetAndroidInputState() {

#if ENABLE_INPUT_SYSTEM
// Ensure we are listening to the most 'current' keyboard...
if (Keyboard.current != _boundKeyboard) {

#if UMI_DEBUG
Debug.Log($"[UMI] Bound Keyboard changed from '{_boundKeyboard}' to '{Keyboard.current}'");
#endif

if (_boundKeyboard != null) {
_boundKeyboard.onTextInput -= OnTextInput;
}

_boundKeyboard = Keyboard.current;

if (_boundKeyboard != null) {
_boundKeyboard.onTextInput += OnTextInput;
}

/// <summary>
/// Store the last input character
/// </summary>
void OnTextInput(char c) {
_lastInputChar = c;
}
}

return new AndroidInputState
{
AnyKey = InputSystem.devices.OfType<Keyboard>().Any(k => k.anyKey.wasPressedThisFrame),
AndroidBack = InputSystem.devices.OfType<Keyboard>().Any(k => k.escapeKey.wasPressedThisFrame),
Backspace = InputSystem.devices.OfType<Keyboard>().Any(k => k.backspaceKey.wasPressedThisFrame),
InputString = _lastInputChar.ToString()
};
#else
return new AndroidInputState
{
AnyKey = Input.anyKeyDown,
AndroidBack = Input.GetKeyDown(KeyCode.Escape),
Backspace = Input.GetKeyUp(KeyCode.Backspace),
InputString = Input.inputString
};
#endif
}
#endif

#if !UNITY_EDITOR

/// <summary>
/// Gets the count of taps in an input-system-agnostic way
/// </summary>
private int GetTapCount() {
#if ENABLE_INPUT_SYSTEM
if (EnhancedTouchSupport.enabled) {
return InputSystemTouch.activeTouches.Count(t => t.isTap);
} else {
return InputSystem.devices.OfType<Touchscreen>().Count(t => t.touches.Any(touch => touch.tap.wasReleasedThisFrame));
}
#else
return GetLegacyInputManagerTouches().Count(t => t.phase == TouchPhase.Ended);
#endif
}

/// <summary>
/// Gets the position of a specific tap in an input-system-agnostic way
/// </summary>
private Vector2 GetTapPosition(int index) {
#if ENABLE_INPUT_SYSTEM
if (EnhancedTouchSupport.enabled) {
return InputSystemTouch.activeTouches.Where(t => t.isTap).ElementAtOrDefault(index).screenPosition;
} else {
return InputSystem.devices.OfType<Touchscreen>().Where(t => t.touches.Any(touch => touch.tap.wasReleasedThisFrame))
.SelectMany(t => t.touches)
.ElementAtOrDefault(index)
.position.ReadValue();
}
#else
return GetLegacyInputManagerTouches()
.Where(t => t.phase == TouchPhase.Ended)
.ElementAtOrDefault(index)
.position;
#endif
}

/// <summary>
/// Convenience enumerator for getting touches from the legacy input manager
/// </summary>
private IEnumerable<LegacyTouch> GetLegacyInputManagerTouches() {
for (var i = 0; i < Input.touchCount; i++) {
yield return Input.GetTouch(i);
}
}
#endif

}
}
}
3 changes: 2 additions & 1 deletion Runtime/UMI.Runtime.asmdef
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "UMI.Runtime",
"rootNamespace": "UMI",
"references": [
"Unity.TextMeshPro"
"Unity.TextMeshPro",
"Unity.InputSystem"
],
"includePlatforms": [],
"excludePlatforms": [],
Expand Down