OldBlueWater/BlueWater/Assets/Doozy/Runtime/UIManager/Input/InputToSignal.cs

272 lines
9.8 KiB
C#

// Copyright (c) 2015 - 2023 Doozy Entertainment. All Rights Reserved.
// This code can only be used under the standard Unity Asset Store End User License Agreement
// A Copy of the EULA APPENDIX 1 is available at http://unity3d.com/company/legal/as_terms
using System;
using System.Collections.Generic;
using Doozy.Runtime.Common.Attributes;
using Doozy.Runtime.Common.Utils;
using Doozy.Runtime.UIManager.ScriptableObjects;
using UnityEngine;
#if INPUT_SYSTEM_PACKAGE
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.UI;
#endif
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable ConvertToAutoPropertyWithPrivateSetter
// ReSharper disable UnusedMember.Global
// ReSharper disable CollectionNeverQueried.Global
namespace Doozy.Runtime.UIManager.Input
{
/// <summary>
/// Bridge that connects the Input System with the Input Stream.
/// It does that by listening for when a specific action has been performed and sends a meta-signal on the Input Stream.
/// </summary>
[AddComponentMenu("Doozy/Input/Input To Signal")]
public class InputToSignal : MonoBehaviour
{
#if UNITY_EDITOR
[UnityEditor.MenuItem("GameObject/Doozy/Input/Input To Signal", false, 8)]
private static void CreateComponent(UnityEditor.MenuCommand menuCommand)
{
GameObjectUtils.AddToScene<InputToSignal>("Input To Signal", false, true);
}
#endif
/// <summary> Reference to the UIManager Input Settings </summary>
public static UIManagerInputSettings inputSettings => UIManagerInputSettings.instance;
[ClearOnReload(newInstance: true)]
// ReSharper disable once CollectionNeverUpdated.Global
public static HashSet<InputToSignal> database { get; } = new HashSet<InputToSignal>();
public static void CleanDatabase() => database.Remove(null);
#if INPUT_SYSTEM_PACKAGE
[SerializeField] private bool AutoConnect;
[SerializeField] private InputSystemUIInputModule UIInputModule;
[SerializeField] private PlayerInput PlayerInput;
[SerializeField] private int PlayerIndex;
[SerializeField] private UIInputActionName InputActionName;
[SerializeField] private string CustomInputActionName;
private InputAction m_Action;
private bool m_IsConnected;
public PlayerInput playerInput => PlayerInput;
public InputSystemUIInputModule uiInputModule => UIInputModule;
public InputAction action => m_Action;
public int playerIndex => hasPlayerInput ? PlayerInput.playerIndex : PlayerIndex;
public string inputActionName => hasCustomActionName ? CustomInputActionName : InputActionName.ToString();
public bool autoConnect => AutoConnect;
public bool isConnected => m_IsConnected;
public bool hasPlayerInput => playerInput != null;
public bool hasUIInputModule => uiInputModule != null;
public bool hasCustomActionName => InputActionName == UIInputActionName.CustomActionName;
private void GetReferences()
{
PlayerInput ??= GetComponent<PlayerInput>();
if (PlayerInput != null)
{
UIInputModule = PlayerInput.uiInputModule;
}
else
{
UIInputModule ??= GetComponent<InputSystemUIInputModule>();
}
}
private void Reset()
{
AutoConnect = true;
PlayerIndex = inputSettings.defaultPlayerIndex;
InputActionName = UIInputActionName.Cancel;
CustomInputActionName = string.Empty;
GetReferences();
}
private void Awake()
{
database.Add(this);
GetReferences();
if (UIInputModule != null) return;
enabled = false;
}
private void OnEnable()
{
CleanDatabase();
if (autoConnect) Connect();
}
private void OnDisable()
{
CleanDatabase();
Disconnect();
}
private void OnDestroy()
{
database.Remove(this);
}
public InputToSignal Connect()
{
if (isConnected) return this;
if (action != null)
{
action.performed -= OnActionPerformed;
m_Action = null;
}
(bool isValid, string message) = IsValid();
if (!isValid)
{
Debug.Log(message);
return this;
}
action.performed += OnActionPerformed;
m_IsConnected = true;
return this;
}
public InputToSignal Disconnect()
{
if (!isConnected) return this;
if (action == null) return this;
action.performed -= OnActionPerformed;
m_IsConnected = false;
return this;
}
public InputToSignal ConnectToAction(UIInputActionName actionName)
{
Disconnect();
m_Action = null;
InputActionName = actionName;
CustomInputActionName = string.Empty;
Connect();
return this;
}
public InputToSignal ConnectToCustomAction(string actionName)
{
Disconnect();
m_Action = null;
InputActionName = UIInputActionName.CustomActionName;
CustomInputActionName = actionName;
Connect();
return this;
}
public InputToSignal ConnectToCustomAction(InputAction inputAction)
{
if (inputAction == null) return this;
Disconnect();
InputActionName = UIInputActionName.CustomActionName;
CustomInputActionName = inputAction.name;
m_Action = inputAction;
Connect();
return this;
}
private void OnActionPerformed(InputAction.CallbackContext context)
{
InputStream.stream.SendSignal(new InputSignalData(InputActionName, context, playerIndex, playerInput));
}
private (bool, string) IsValid()
{
if (m_Action != null) return (true, "Valid");
if (UIInputModule == null) return (false, $"Not Valid: {nameof(UIInputModule)} is null");
m_Action = null;
m_Action = InputActionName switch
{
UIInputActionName.Point => UIInputModule.point.action,
UIInputActionName.Click => UIInputModule.leftClick.action,
UIInputActionName.MiddleClick => UIInputModule.middleClick.action,
UIInputActionName.RightClick => UIInputModule.rightClick.action,
UIInputActionName.ScrollWheel => UIInputModule.scrollWheel.action,
UIInputActionName.Navigate => UIInputModule.move.action,
UIInputActionName.Submit => UIInputModule.submit.action,
UIInputActionName.Cancel => UIInputModule.cancel.action,
UIInputActionName.TrackedDevicePosition => UIInputModule.trackedDevicePosition.action,
UIInputActionName.TrackedDeviceOrientation => UIInputModule.trackedDeviceOrientation.action,
UIInputActionName.CustomActionName => UIInputModule.actionsAsset.FindAction(CustomInputActionName),
_ => throw new ArgumentOutOfRangeException()
};
return
m_Action == null
? (false, $"Not Valid: {nameof(m_Action)} is null")
: (true, "Valid");
}
#endif
#if LEGACY_INPUT_MANAGER
public const KeyCode k_BackButtonKeyCode = KeyCode.Escape;
public const string k_BackButtonVirtualButtonName = "Cancel";
[SerializeField] private LegacyInputMode InputMode;
[SerializeField] private KeyCode KeyCode;
[SerializeField] private string VirtualButtonName;
[SerializeField] private int PlayerIndex;
public LegacyInputMode inputMode
{
get => InputMode;
set => InputMode = value;
}
public KeyCode keyCode
{
get => KeyCode;
set => KeyCode = value;
}
public string virtualButtonName
{
get => VirtualButtonName;
set => VirtualButtonName = value;
}
public int playerIndex
{
get => PlayerIndex;
set => PlayerIndex = value;
}
private void Reset()
{
InputMode = LegacyInputMode.None;
KeyCode = default;
VirtualButtonName = string.Empty;
PlayerIndex = inputSettings.defaultPlayerIndex;
}
private void Update()
{
if (UISettings.interactionsDisabled) return;
bool execute;
switch (InputMode)
{
case LegacyInputMode.None:
execute = false;
break;
case LegacyInputMode.KeyCode:
execute = UnityEngine.Input.GetKeyDown(keyCode);
break;
case LegacyInputMode.VirtualButton:
execute = UnityEngine.Input.GetButtonDown(virtualButtonName);
break;
default:
throw new ArgumentOutOfRangeException();
}
if (!execute) return;
InputStream.stream.SendSignal(new InputSignalData(inputMode, keyCode, virtualButtonName, playerIndex));
}
#endif
}
}