From 296a7f2958b5244fe26d0d6477f51846e45cf2b2 Mon Sep 17 00:00:00 2001 From: Reinier Vens Date: Thu, 6 May 2021 02:34:19 +0100 Subject: [PATCH] Input Screen Refactoring Cleaned up the code for the input screen and refactored to prepare for mouse binding Consolidated wormhole and dock keys into one "Interact" key --- Asset Sources/Mouse.png | 3 + Asset Sources/Mouse.psd | 3 + Asset Sources/Mouse_0000_Forward-copy.png | 3 + Asset Sources/Mouse_0000_Layer-5.png | 3 + Asset Sources/Mouse_0001_Forward.png | 3 + Asset Sources/Mouse_0001_Layer-4.png | 3 + Asset Sources/Mouse_0002_Layer-3.png | 3 + Asset Sources/Mouse_0002_Middle-copy.png | 3 + Asset Sources/Mouse_0003_Layer-8.png | 3 + Asset Sources/Mouse_0003_Middle.png | 3 + Asset Sources/Mouse_0004_Layer-9.png | 3 + Asset Sources/Mouse_0004_Right-copy.png | 3 + Asset Sources/Mouse_0005_Layer-10-copy.png | 3 + Asset Sources/Mouse_0005_Right.png | 3 + Asset Sources/Mouse_0006_Layer-10.png | 3 + Asset Sources/Mouse_0006_Left-copy.png | 3 + Asset Sources/Mouse_0007_Left.png | 3 + Assets/InputDisplayButton.cs | 10 + Assets/InputDisplayButton.cs.meta | 11 + Assets/InputDisplayKey.cs | 4 +- Assets/InputDisplayLayout.cs | 344 ++--- Assets/InputLayout.cs | 32 +- Assets/Resources/Aetheria.inputactions | 70 +- Assets/Resources/Sprites/Icons/Mouse.meta | 8 + .../Resources/Sprites/Icons/Mouse/Mouse.png | 3 + .../Sprites/Icons/Mouse/Mouse.png.meta | 108 ++ .../Sprites/Icons/Mouse/Mouse_Left_fill.png | 3 + .../Icons/Mouse/Mouse_Left_fill.png.meta | 108 ++ .../Icons/Mouse/Mouse_Left_outline.png | 3 + .../Icons/Mouse/Mouse_Left_outline.png.meta | 108 ++ .../Sprites/Icons/Mouse/Mouse_Middle_fill.png | 3 + .../Icons/Mouse/Mouse_Middle_fill.png.meta | 108 ++ .../Icons/Mouse/Mouse_Middle_outline.png | 3 + .../Icons/Mouse/Mouse_Middle_outline.png.meta | 108 ++ .../Sprites/Icons/Mouse/Mouse_Right_fill.png | 3 + .../Icons/Mouse/Mouse_Right_fill.png.meta | 108 ++ .../Icons/Mouse/Mouse_Right_outline.png | 3 + .../Icons/Mouse/Mouse_Right_outline.png.meta | 108 ++ .../Sprites/Icons/Mouse/Mouse_Side_fill.png | 3 + .../Icons/Mouse/Mouse_Side_fill.png.meta | 108 ++ .../Icons/Mouse/Mouse_Side_outline.png | 3 + .../Icons/Mouse/Mouse_Side_outline.png.meta | 108 ++ Assets/Scenes/InputScreenTest.unity | 1137 ++++++++++++++++- Assets/Scripts/AetheriaInput.cs | 110 +- Assets/Scripts/Gameplay/ActionGameManager.cs | 59 +- Assets/Scripts/ServerShared/PlayerSettings.cs | 28 +- Assets/Scripts/UI/MainMenu.cs | 8 +- 47 files changed, 2577 insertions(+), 294 deletions(-) create mode 100644 Asset Sources/Mouse.png create mode 100644 Asset Sources/Mouse.psd create mode 100644 Asset Sources/Mouse_0000_Forward-copy.png create mode 100644 Asset Sources/Mouse_0000_Layer-5.png create mode 100644 Asset Sources/Mouse_0001_Forward.png create mode 100644 Asset Sources/Mouse_0001_Layer-4.png create mode 100644 Asset Sources/Mouse_0002_Layer-3.png create mode 100644 Asset Sources/Mouse_0002_Middle-copy.png create mode 100644 Asset Sources/Mouse_0003_Layer-8.png create mode 100644 Asset Sources/Mouse_0003_Middle.png create mode 100644 Asset Sources/Mouse_0004_Layer-9.png create mode 100644 Asset Sources/Mouse_0004_Right-copy.png create mode 100644 Asset Sources/Mouse_0005_Layer-10-copy.png create mode 100644 Asset Sources/Mouse_0005_Right.png create mode 100644 Asset Sources/Mouse_0006_Layer-10.png create mode 100644 Asset Sources/Mouse_0006_Left-copy.png create mode 100644 Asset Sources/Mouse_0007_Left.png create mode 100644 Assets/InputDisplayButton.cs create mode 100644 Assets/InputDisplayButton.cs.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Left_fill.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Left_fill.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Left_outline.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Left_outline.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Middle_fill.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Middle_fill.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Middle_outline.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Middle_outline.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Right_fill.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Right_fill.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Right_outline.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Right_outline.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Side_fill.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Side_fill.png.meta create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Side_outline.png create mode 100644 Assets/Resources/Sprites/Icons/Mouse/Mouse_Side_outline.png.meta diff --git a/Asset Sources/Mouse.png b/Asset Sources/Mouse.png new file mode 100644 index 000000000..c71018e8f --- /dev/null +++ b/Asset Sources/Mouse.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fcb71c61aaec4f933bcedd1c6cdc28a091d10150a208951f481875b287b439ae +size 30936 diff --git a/Asset Sources/Mouse.psd b/Asset Sources/Mouse.psd new file mode 100644 index 000000000..3a34f6f29 --- /dev/null +++ b/Asset Sources/Mouse.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9c5cc3f45986c9617fd988c9abd39317873079541f0fce4890dcc49da6e9c04a +size 200097 diff --git a/Asset Sources/Mouse_0000_Forward-copy.png b/Asset Sources/Mouse_0000_Forward-copy.png new file mode 100644 index 000000000..a9fbd2f17 --- /dev/null +++ b/Asset Sources/Mouse_0000_Forward-copy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4528458e8269bb63b39a3c71dd18a6e89289e80fd9b3963c96037fe9860448b9 +size 3764 diff --git a/Asset Sources/Mouse_0000_Layer-5.png b/Asset Sources/Mouse_0000_Layer-5.png new file mode 100644 index 000000000..4af86806b --- /dev/null +++ b/Asset Sources/Mouse_0000_Layer-5.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:266c49341ee0f8ca416498900b0fab360af077a1590d62f83f72c51609ec96eb +size 4516 diff --git a/Asset Sources/Mouse_0001_Forward.png b/Asset Sources/Mouse_0001_Forward.png new file mode 100644 index 000000000..1db9b6653 --- /dev/null +++ b/Asset Sources/Mouse_0001_Forward.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d5af6be54c37586e83d0cedead0e25624654ba8462b2fc3f150e2ff86a9e05f +size 3710 diff --git a/Asset Sources/Mouse_0001_Layer-4.png b/Asset Sources/Mouse_0001_Layer-4.png new file mode 100644 index 000000000..9c61889ed --- /dev/null +++ b/Asset Sources/Mouse_0001_Layer-4.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e7d0bef19a451cfe53b34e145d5ba2ac260baaca7ec1ba15f19c6d19dd15abd5 +size 6127 diff --git a/Asset Sources/Mouse_0002_Layer-3.png b/Asset Sources/Mouse_0002_Layer-3.png new file mode 100644 index 000000000..613f73c3e --- /dev/null +++ b/Asset Sources/Mouse_0002_Layer-3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2e8cefcecf39d3df12cfd1ee1cbef38f22519d50be2c1709636254840026c0c7 +size 6229 diff --git a/Asset Sources/Mouse_0002_Middle-copy.png b/Asset Sources/Mouse_0002_Middle-copy.png new file mode 100644 index 000000000..43e073f90 --- /dev/null +++ b/Asset Sources/Mouse_0002_Middle-copy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e287fc218e5c1034eb5ba7955bc2ed7bedd324549f1e7d7259b343b22e67445 +size 4429 diff --git a/Asset Sources/Mouse_0003_Layer-8.png b/Asset Sources/Mouse_0003_Layer-8.png new file mode 100644 index 000000000..a76a11a39 --- /dev/null +++ b/Asset Sources/Mouse_0003_Layer-8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:171e5eb85c4198489d3f82ed32c48be38db7b203b6fd6a31955d32d09c6dd5ac +size 3913 diff --git a/Asset Sources/Mouse_0003_Middle.png b/Asset Sources/Mouse_0003_Middle.png new file mode 100644 index 000000000..42804a6ed --- /dev/null +++ b/Asset Sources/Mouse_0003_Middle.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:112605667ec859131219790eb10a732ad2f4e0188b7ad89ca74fa943a4f0a1c0 +size 4242 diff --git a/Asset Sources/Mouse_0004_Layer-9.png b/Asset Sources/Mouse_0004_Layer-9.png new file mode 100644 index 000000000..48053c0ff --- /dev/null +++ b/Asset Sources/Mouse_0004_Layer-9.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:892b17d93c31a81c25a0aa2cac7ce782ba766a351891448e4d065db406301e65 +size 3918 diff --git a/Asset Sources/Mouse_0004_Right-copy.png b/Asset Sources/Mouse_0004_Right-copy.png new file mode 100644 index 000000000..457d269ac --- /dev/null +++ b/Asset Sources/Mouse_0004_Right-copy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ee786ccb49ca207821d67da20a2efc5e7fc9cc303c5c58b54c7632e19e31b8d +size 6158 diff --git a/Asset Sources/Mouse_0005_Layer-10-copy.png b/Asset Sources/Mouse_0005_Layer-10-copy.png new file mode 100644 index 000000000..dbb759be5 --- /dev/null +++ b/Asset Sources/Mouse_0005_Layer-10-copy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6d470249f79ef41f068446ec66beebf9c8a28077a2ee4c4f487167b2c4faa367 +size 14663 diff --git a/Asset Sources/Mouse_0005_Right.png b/Asset Sources/Mouse_0005_Right.png new file mode 100644 index 000000000..6042acbf0 --- /dev/null +++ b/Asset Sources/Mouse_0005_Right.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c87fa62d61f6ba9c4ad978f4e8c3bcc97825e3023ba2f5a6b5f16b061057b80c +size 5279 diff --git a/Asset Sources/Mouse_0006_Layer-10.png b/Asset Sources/Mouse_0006_Layer-10.png new file mode 100644 index 000000000..932852250 --- /dev/null +++ b/Asset Sources/Mouse_0006_Layer-10.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79d9d5a21e49f529203c42ac4ef91552d24bfd26353bb6313f8643160b92dcce +size 14715 diff --git a/Asset Sources/Mouse_0006_Left-copy.png b/Asset Sources/Mouse_0006_Left-copy.png new file mode 100644 index 000000000..59a13437a --- /dev/null +++ b/Asset Sources/Mouse_0006_Left-copy.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f6efc0d9049aa085afb7711cd8aebd3a000067769de3336ef5d404b75cafc502 +size 6206 diff --git a/Asset Sources/Mouse_0007_Left.png b/Asset Sources/Mouse_0007_Left.png new file mode 100644 index 000000000..dfe82c2b9 --- /dev/null +++ b/Asset Sources/Mouse_0007_Left.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:813f030da5695b6996098dad4a90e7fbf9169278ea6b1aa4bf7e8e0c216ffe7a +size 5323 diff --git a/Assets/InputDisplayButton.cs b/Assets/InputDisplayButton.cs new file mode 100644 index 000000000..b0a686d93 --- /dev/null +++ b/Assets/InputDisplayButton.cs @@ -0,0 +1,10 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.UI; + +public class InputDisplayButton : MonoBehaviour +{ + public Image Fill; + public Image Outline; +} diff --git a/Assets/InputDisplayButton.cs.meta b/Assets/InputDisplayButton.cs.meta new file mode 100644 index 000000000..62382bc93 --- /dev/null +++ b/Assets/InputDisplayButton.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9ed1d3c353acc9a489cb65f1c7726814 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/InputDisplayKey.cs b/Assets/InputDisplayKey.cs index f3d24d400..fdc0a18fd 100644 --- a/Assets/InputDisplayKey.cs +++ b/Assets/InputDisplayKey.cs @@ -4,11 +4,9 @@ using TMPro; using UnityEngine; using UnityEngine.UI; -public class InputDisplayKey : MonoBehaviour +public class InputDisplayKey : InputDisplayButton { public TextMeshProUGUI MainLabel; public TextMeshProUGUI AltLabel; - public Image Fill; - public Image Outline; public LayoutElement LayoutElement; } diff --git a/Assets/InputDisplayLayout.cs b/Assets/InputDisplayLayout.cs index 1dbe43078..3a3eb22f2 100644 --- a/Assets/InputDisplayLayout.cs +++ b/Assets/InputDisplayLayout.cs @@ -16,6 +16,12 @@ using static Unity.Mathematics.math; public class InputDisplayLayout : MonoBehaviour { + public RectTransform UnassignedBindingsGroup; + public InputDisplayButton MouseLeft; + public InputDisplayButton MouseRight; + public InputDisplayButton MouseMiddle; + public InputDisplayButton MouseForward; + public InputDisplayButton MouseBack; public VerticalLayoutGroup RowContainer; public TextAsset LayoutFile; public Prototype LabelPrototype; @@ -30,41 +36,51 @@ public class InputDisplayLayout : MonoBehaviour public float FillAlpha; public float FillMultiplier = .25f; public float InactiveMultiplier = .333f; - public int TestSteps = 5; + public int PlacementSearchArea = 4; public float TestPadding = 4; public float BoxLineExpand = -1; - public Color GlobalColor; - public float GlobalHueBuffer = .1f; + public float GlobalHue = .333f; + public float Saturation; + public float GlobalHueRange = .1f; private Canvas _canvas; - private Color _defaultInactiveColor; private InputLayout _inputLayout; - private Dictionary _displayKeys = new Dictionary(); - private Dictionary _bindKeys = new Dictionary(); - private Dictionary _actionMap = new Dictionary(); - private Dictionary _actionLabels = new Dictionary(); - private Dictionary _actionColors = new Dictionary(); - private List _reservedRects = new List(); - private List _layoutGroups = new List(); + + private class ButtonMapping + { + public IBindableButton Button; + public InputDisplayButton DisplayButton; + public ActionMapping ActionMapping; + public Rect ButtonRect; + public UILineRenderer LabelLine; + } + + private class ActionMapping + { + public InputAction Action; + public TextMeshProUGUI Label; + public Rect LabelRect; + public float Hue; + public List ButtonMappings = new List(); + } - private string FullKeyPath(string shortPath) => $"/{shortPath}"; - private string ShortKeyPath(string fullPath) => fullPath.Substring(fullPath.LastIndexOf('/') + 1); + private Dictionary _bindButtons = new Dictionary(); + private List _buttonMappings = new List(); + private List _actionMappings = new List(); void Start() { _canvas = transform.root.GetComponent(); - _defaultInactiveColor = DefaultColor; - _defaultInactiveColor.a *= InactiveMultiplier; var path = Path.Combine(ActionGameManager.GameDataDirectory.CreateSubdirectory("KeyboardLayouts").FullName, $"{LayoutFile.name}.msgpack"); // _inputLayout = ParseJson(LayoutFile.text); RegisterResolver.Register(); _inputLayout = MessagePackSerializer.Deserialize(File.ReadAllBytes(path)); DisplayLayout(_inputLayout); - - foreach (var key in _inputLayout.GetBindableKeys()) - { - var fullInputPath = FullKeyPath(key.InputSystemPath); - _bindKeys[fullInputPath] = key; + + foreach (var buttonMapping in _buttonMappings) _bindButtons[buttonMapping.Button.InputSystemPath] = buttonMapping; + + // foreach (var key in _inputLayout.GetBindableKeys()) + // { // var keyPress = new InputAction(binding: fullInputPath); // keyPress.started += context => // { @@ -85,129 +101,161 @@ public class InputDisplayLayout : MonoBehaviour // displayKey.Fill.color = fillColor; // }; // keyPress.Enable(); - } - - var input = new AetheriaInput(); - // input.Global.Dock.performed += context => Debug.Log("Docking!"); - // input.Global.GalaxyMap.performed += context => - // { - // input.Global.Dock.Disable(); - // var rebindOperation = input.Global.Dock.PerformInteractiveRebinding() - // .WithControlsExcluding("Mouse") - // .WithCancelingThrough("/escape") - // .OnMatchWaitForAnother(0.2f) - // .Start(); - // Debug.Log("Rebinding Dock!"); - // rebindOperation.OnComplete(operation => - // { - // Debug.Log("Rebinding Complete!"); - // input.Global.Dock.Enable(); - // }); - // }; - // input.Enable(); - - _layoutGroups.Add(RowContainer); - // foreach (var group in _layoutGroups) - // { - // group.CalculateLayoutInputHorizontal(); - // group.CalculateLayoutInputVertical(); - // group.SetLayoutHorizontal(); - // group.SetLayoutVertical(); - // LayoutRebuilder.ForceRebuildLayoutImmediate(group.GetComponent()); // } - // LayoutRebuilder.ForceRebuildLayoutImmediate(GetComponent()); + Canvas.ForceUpdateCanvases(); - Color.RGBToHSV(GlobalColor, out var hue, out var saturation, out var value); - var actionIndex = 0; - var actionCount = (float) input.asset.Count(a=>a.actionMap.name!="UI"); - foreach (var action in input.asset) - { - if(action.actionMap.name=="UI") continue; - var h = frac(hue + GlobalHueBuffer + actionIndex++ / actionCount * (1 - GlobalHueBuffer * 2)); - if (action.actionMap.name == "Global") - { - h = hue; - _actionColors[action] = GlobalColor; - } - else - _actionColors[action] = Color.HSVToRGB(h, saturation, value); - foreach (var binding in action.bindings) - { - if (_bindKeys.ContainsKey(binding.path)) - { - var displayKey = _displayKeys[_bindKeys[binding.path]]; - displayKey.Fill.color = Color.HSVToRGB(h, saturation, FillBrightness); - displayKey.Outline.gameObject.SetActive(true); - displayKey.Outline.color = displayKey.MainLabel.color = displayKey.AltLabel.color = _actionColors[action]; - _actionMap[displayKey] = action; - _reservedRects.Add(displayKey.GetComponent().ScreenSpaceRect()); - } - } - } - - var center = _actionMap.Keys.Aggregate(Vector2.zero, (v, displayKey) => v + (Vector2) displayKey.transform.position) / _actionMap.Keys.Count; - - foreach (var x in _actionMap) - { - var key = x.Key; - var action = x.Value; - if(_actionLabels.ContainsKey(action)) continue; - - var label = LabelPrototype.Instantiate(); - label.color = _actionColors[action]; - _actionLabels[action] = label; - var labelRect = label.rectTransform; - label.text = _actionMap[key].name.Replace(' ', '\n'); - LayoutRebuilder.ForceRebuildLayoutImmediate(labelRect); - var pos = (Vector2) key.transform.position; - var dir = (pos - center).normalized; - label.transform.position = FindLabelPosition(key.GetComponent(), labelRect, dir); - } + foreach (var buttonMapping in _buttonMappings) + buttonMapping.ButtonRect = buttonMapping.DisplayButton.GetComponent().ScreenSpaceRect(); - foreach (var x in _actionMap) - { - var key = x.Key; - var action = x.Value; - - var keyBounds = key.Outline.rectTransform.GetBounds(BoxLineExpand); - var labelPoint = (Vector2) _actionLabels[action].rectTransform.GetBounds().ClosestPoint(key.Outline.transform.position); - var keyPoint = (Vector2) keyBounds.ClosestPoint(labelPoint); + var input = new AetheriaInput(); + ProcessActions(input.asset); - var line = LinePrototype.Instantiate(); - line.color = _actionColors[action]; - line.Points = new[] { keyPoint, labelPoint }; + foreach (var actionMapping in _actionMappings) + { + actionMapping.Label = CreateLabel(actionMapping); + PlaceLabel(actionMapping); + foreach(var buttonMapping in actionMapping.ButtonMappings) ConnectButtonToLabel(buttonMapping); } //StartCoroutine(AssociateInputKeys(_inputLayout)); } - private Vector2 FindLabelPosition(RectTransform key, RectTransform label, Vector2 dir) + private void ProcessActions(InputActionAsset input) + { + var nonUIActions = input.Where(a => a.actionMap.name != "UI").ToArray(); + for (var i = 0; i < nonUIActions.Length; i++) + { + var action = nonUIActions[i]; + var actionMapping = new ActionMapping + { + Action = action, + Hue = action.actionMap.name == "Global" + ? GlobalHue + : frac(GlobalHue + GlobalHueRange + (float) i / (nonUIActions.Length - 1) * (1 - GlobalHueRange * 2)) + }; + _actionMappings.Add(actionMapping); + foreach (var binding in action.bindings) + { + if (_bindButtons.ContainsKey(binding.path)) + { + var buttonMapping = _bindButtons[binding.path]; + buttonMapping.ActionMapping = actionMapping; + AssignColor(buttonMapping); + actionMapping.ButtonMappings.Add(buttonMapping); + } + } + } + } + + private void AssignColor(ButtonMapping buttonMapping) + { + if(buttonMapping.ActionMapping!=null) + { + var outlineColor = Color.HSVToRGB(buttonMapping.ActionMapping.Hue, Saturation, 1); + var fillColor = Color.HSVToRGB(buttonMapping.ActionMapping.Hue, 1, FillBrightness); + fillColor.a = FillAlpha; + buttonMapping.DisplayButton.Fill.color = fillColor; + buttonMapping.DisplayButton.Outline.gameObject.SetActive(true); + buttonMapping.DisplayButton.Outline.color = outlineColor; + if (buttonMapping.DisplayButton is InputDisplayKey key) key.MainLabel.color = key.AltLabel.color = outlineColor; + } + else AssignUnboundColor(buttonMapping.DisplayButton); + } + + private void AssignUnboundColor(InputDisplayButton button, bool bindable = true) + { + button.Outline.gameObject.SetActive(false); + var outlineColor = DefaultColor; + outlineColor.a *= InactiveMultiplier; + var fillColor = DefaultColor * FillBrightness; + fillColor *= FillBrightness; + if(!bindable) + fillColor *= InactiveMultiplier; + fillColor.a = FillAlpha; + button.Fill.color = fillColor; + if (button is InputDisplayKey key) key.MainLabel.color = key.AltLabel.color = Color.Lerp(outlineColor, fillColor, .5f); + } + + private TextMeshProUGUI CreateLabel(ActionMapping actionMapping) + { + var label = LabelPrototype.Instantiate(); + label.color = Color.HSVToRGB(actionMapping.Hue, Saturation, 1); + actionMapping.Label = label; + label.text = actionMapping.Action.name.Replace(' ', '\n'); + return label; + } + + private void PlaceLabel(ActionMapping actionMapping) + { + if(actionMapping.ButtonMappings.Any()) + { + var labelRect = actionMapping.Label.rectTransform; + LayoutRebuilder.ForceRebuildLayoutImmediate(labelRect); + var rect = FindLabelPosition(actionMapping.ButtonMappings.First().DisplayButton.GetComponent(), labelRect); + actionMapping.LabelRect = rect; + actionMapping.Label.transform.position = rect.center; + } + else + { + actionMapping.Label.rectTransform.parent = UnassignedBindingsGroup; + } + } + + private void ConnectButtonToLabel(ButtonMapping buttonMapping) + { + if (buttonMapping.ActionMapping != null) + { + var keyBounds = buttonMapping.DisplayButton.Outline.rectTransform.GetBounds(BoxLineExpand); + var labelPoint = (Vector2) buttonMapping.ActionMapping.Label.rectTransform.GetBounds().ClosestPoint(keyBounds.center); + var keyPoint = (Vector2) keyBounds.ClosestPoint(labelPoint); + labelPoint /= _canvas.scaleFactor; + keyPoint /= _canvas.scaleFactor; + + buttonMapping.LabelLine ??= LinePrototype.Instantiate(); + buttonMapping.LabelLine.color = buttonMapping.ActionMapping.Label.color; + buttonMapping.LabelLine.Points = new[] {keyPoint, labelPoint}; + } + else + { + buttonMapping.LabelLine?.GetComponent().ReturnToPool(); + buttonMapping.LabelLine = null; + } + } + + private Rect FindLabelPosition(RectTransform key, RectTransform label) { var keyRect = key.ScreenSpaceRect(); - var labelRect = label.ScreenSpaceRect(TestPadding); - var localRects = Overlap(key.ScreenSpaceRect(TestSteps * KeySize)); + var labelRect = label.ScreenSpaceRect(TestPadding*_canvas.scaleFactor); + var localRects = Overlap(key.ScreenSpaceRect(PlacementSearchArea * KeySize * _canvas.scaleFactor)); + var centroid = localRects.Aggregate(Vector2.zero, (v, r) => v + r.center) / localRects.Length; var keyCenter = keyRect.center; - for (int dist = KeySize; dist < TestSteps * KeySize; dist++) + var dir = (keyCenter - centroid).normalized; + for (int dist = KeySize; dist < PlacementSearchArea * KeySize; dist++) { for (float theta = 0; theta < PI * 2; theta += PI / 32) { for (int s = -1; s <= 1; s += 2) { - var testPos = keyCenter + dir.Rotate(theta * s) * dist; + var testPos = keyCenter + dir.Rotate(theta * s) * dist * _canvas.scaleFactor; var testRect = new Rect(testPos - labelRect.size / 2, labelRect.size); if(!localRects.Any(r => r.Overlaps(testRect))) { - _reservedRects.Add(testRect); - return testPos; + return testRect; } } } } - return Vector2.zero; + return default; } - private Rect[] Overlap(Rect rect) => _reservedRects.Where(r => r.Overlaps(rect)).ToArray(); + private Rect[] Overlap(Rect rect) => _buttonMappings + .Where(b=>b.ActionMapping!=null) + .Select(b=>b.ButtonRect) + .Concat(_actionMappings + .Where(a=>a.LabelRect.width > .1f) + .Select(a=>a.LabelRect)) + .Where(r => r.Overlaps(rect)).ToArray(); public void DisplayLayout(InputLayout layout) { @@ -216,7 +264,6 @@ public class InputDisplayLayout : MonoBehaviour if (row is InputLayoutKeyRow keyRow) { var displayRow = RowPrototype.Instantiate(); - _layoutGroups.Add(displayRow.LayoutGroup); foreach (var column in keyRow.Columns) { if (column is InputLayoutColumnSpacer) @@ -230,14 +277,17 @@ public class InputDisplayLayout : MonoBehaviour displayKey.LayoutElement.preferredWidth = KeySize * column.Width; displayKey.Outline.gameObject.SetActive(false); displayKey.Outline.color = DefaultColor; - var fillColor = DefaultColor; - fillColor *= FillMultiplier; - fillColor.a = FillAlpha; - displayKey.MainLabel.color = displayKey.AltLabel.color = Color.Lerp(_defaultInactiveColor, fillColor, .5f); + AssignUnboundColor(displayKey, column is InputLayoutBindableKey); if (column is InputLayoutBindableKey key) { - _displayKeys[key] = displayKey; + var buttonMapping = new ButtonMapping + { + Button = key, + DisplayButton = displayKey + }; + _bindButtons[key.InputSystemPath] = buttonMapping; + _buttonMappings.Add(buttonMapping); displayKey.MainLabel.text = key.MainLabel; displayKey.AltLabel.text = key.AltLabel; @@ -251,11 +301,9 @@ public class InputDisplayLayout : MonoBehaviour } else { - fillColor.a *= InactiveMultiplier; displayKey.MainLabel.text = ""; displayKey.AltLabel.text = ""; } - displayKey.Fill.color = fillColor; } else { @@ -348,51 +396,41 @@ public class InputDisplayLayout : MonoBehaviour return new InputLayout {Rows = rows.ToArray()}; } - private IEnumerator AssociateInputKeys(InputLayout layout) + private IEnumerator AssociateInputKeys() { var path = ""; var keyPress = new InputAction(binding: "//