diff --git a/.gitignore b/.gitignore index 72e8d42e5..44906c47c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ /[Ll]ogs/ /[Mm]emoryCaptures/ /Recordings/ +/Assets/StreamingAssets/Audio/GeneratedSoundBanks/ # Wwise folders /Aetheria-Economy_WwiseProject/.backup diff --git a/AK.Wwise.Unity.API.Editor.csproj b/AK.Wwise.Unity.API.Editor.csproj index cfa172440..788fb2bee 100644 --- a/AK.Wwise.Unity.API.Editor.csproj +++ b/AK.Wwise.Unity.API.Editor.csproj @@ -310,9 +310,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -343,6 +340,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Projects/Aetheria-Economy/Library/PackageCache/com.unity.ext.nunit@1.0.6/net35/unity-custom/nunit.framework.dll diff --git a/AK.Wwise.Unity.API.WwiseTypes.csproj b/AK.Wwise.Unity.API.WwiseTypes.csproj index e5df91b3b..358417c02 100644 --- a/AK.Wwise.Unity.API.WwiseTypes.csproj +++ b/AK.Wwise.Unity.API.WwiseTypes.csproj @@ -308,9 +308,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -341,6 +338,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Applications/Unity Editors/2020.3.2f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll diff --git a/AK.Wwise.Unity.API.csproj b/AK.Wwise.Unity.API.csproj index ed55ca55f..b5050d234 100644 --- a/AK.Wwise.Unity.API.csproj +++ b/AK.Wwise.Unity.API.csproj @@ -416,9 +416,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -449,6 +446,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Applications/Unity Editors/2020.3.2f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll diff --git a/AK.Wwise.Unity.MonoBehaviour.Editor.csproj b/AK.Wwise.Unity.MonoBehaviour.Editor.csproj index af49adf1a..a40532910 100644 --- a/AK.Wwise.Unity.MonoBehaviour.Editor.csproj +++ b/AK.Wwise.Unity.MonoBehaviour.Editor.csproj @@ -309,9 +309,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -342,6 +339,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Projects/Aetheria-Economy/Library/PackageCache/com.unity.ext.nunit@1.0.6/net35/unity-custom/nunit.framework.dll diff --git a/AK.Wwise.Unity.MonoBehaviour.csproj b/AK.Wwise.Unity.MonoBehaviour.csproj index 8de3898aa..027d1b7f3 100644 --- a/AK.Wwise.Unity.MonoBehaviour.csproj +++ b/AK.Wwise.Unity.MonoBehaviour.csproj @@ -330,9 +330,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -363,6 +360,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Applications/Unity Editors/2020.3.2f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll diff --git a/AK.Wwise.Unity.Timeline.Editor.csproj b/AK.Wwise.Unity.Timeline.Editor.csproj index b2dbcd5e4..a7fb95a0d 100644 --- a/AK.Wwise.Unity.Timeline.Editor.csproj +++ b/AK.Wwise.Unity.Timeline.Editor.csproj @@ -287,9 +287,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -320,6 +317,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Projects/Aetheria-Economy/Library/PackageCache/com.unity.ext.nunit@1.0.6/net35/unity-custom/nunit.framework.dll diff --git a/AK.Wwise.Unity.Timeline.csproj b/AK.Wwise.Unity.Timeline.csproj index 2328d093d..ffbe622ad 100644 --- a/AK.Wwise.Unity.Timeline.csproj +++ b/AK.Wwise.Unity.Timeline.csproj @@ -293,9 +293,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -326,6 +323,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Applications/Unity Editors/2020.3.2f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll diff --git a/Aetheria-Economy_WwiseProject/Actor-Mixer Hierarchy/SFX.wwu b/Aetheria-Economy_WwiseProject/Actor-Mixer Hierarchy/SFX.wwu index a73496b47..c085d13dc 100644 --- a/Aetheria-Economy_WwiseProject/Actor-Mixer Hierarchy/SFX.wwu +++ b/Aetheria-Economy_WwiseProject/Actor-Mixer Hierarchy/SFX.wwu @@ -3101,9 +3101,9 @@ - + - + @@ -3229,7 +3229,7 @@ - + @@ -3367,7 +3367,7 @@ - + @@ -3501,7 +3501,7 @@ - + @@ -3543,7 +3543,7 @@ - + @@ -3695,7 +3695,7 @@ - + @@ -5524,7 +5524,7 @@ - + @@ -6152,7 +6152,7 @@ - -4.4 + 4.6 @@ -6195,7 +6195,12 @@ + + + + + @@ -6697,6 +6702,11 @@ + + + False + + diff --git a/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.validationcache b/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.validationcache index 166d4b7da..db2124fe7 100644 --- a/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.validationcache +++ b/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.validationcache @@ -6,7 +6,7 @@ - + @@ -18,29 +18,29 @@ - + - - + + - - + + - + - + - + - + - + diff --git a/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.wsettings b/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.wsettings index d783f10cd..785b02ffb 100644 --- a/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.wsettings +++ b/Aetheria-Economy_WwiseProject/Aetheria-Economy_WwiseProject.rwvens.wsettings @@ -115,9 +115,9 @@ - + - + @@ -150,9 +150,9 @@ - + - + @@ -161,7 +161,7 @@ - + @@ -173,11 +173,11 @@ - - + + - + @@ -200,7 +200,7 @@ - + diff --git a/Aetheria-Economy_WwiseProject/Effects/Default Work Unit.wwu b/Aetheria-Economy_WwiseProject/Effects/Default Work Unit.wwu index 71c60c034..33131d3ff 100644 --- a/Aetheria-Economy_WwiseProject/Effects/Default Work Unit.wwu +++ b/Aetheria-Economy_WwiseProject/Effects/Default Work Unit.wwu @@ -167,6 +167,12 @@ + + 462899 + + + + 462899 diff --git a/Aetheria-Economy_WwiseProject/Events/SFX.wwu b/Aetheria-Economy_WwiseProject/Events/SFX.wwu index 1ac023859..73d9d1117 100644 --- a/Aetheria-Economy_WwiseProject/Events/SFX.wwu +++ b/Aetheria-Economy_WwiseProject/Events/SFX.wwu @@ -53,75 +53,75 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -129,7 +129,7 @@ - + @@ -434,13 +434,6 @@ - - - - False - - - @@ -448,13 +441,6 @@ - - - - False - - - @@ -573,13 +559,6 @@ - - - - False - - - @@ -633,13 +612,6 @@ - - - - False - - - diff --git a/Aetheria-Economy_WwiseProject/Game Parameters/SFX.wwu b/Aetheria-Economy_WwiseProject/Game Parameters/SFX.wwu index 23230789b..2877d254d 100644 --- a/Aetheria-Economy_WwiseProject/Game Parameters/SFX.wwu +++ b/Aetheria-Economy_WwiseProject/Game Parameters/SFX.wwu @@ -11,12 +11,6 @@ - - - - - - @@ -96,6 +90,12 @@ + + + + + + diff --git a/Aetheria-Economy_WwiseProject/SoundBanks/SFX.wwu b/Aetheria-Economy_WwiseProject/SoundBanks/SFX.wwu index f10605547..8fce992ea 100644 --- a/Aetheria-Economy_WwiseProject/SoundBanks/SFX.wwu +++ b/Aetheria-Economy_WwiseProject/SoundBanks/SFX.wwu @@ -13,10 +13,10 @@ - + - - + + diff --git a/Aetheria-Economy_WwiseProject/Soundcaster Sessions/Default Work Unit.wwu b/Aetheria-Economy_WwiseProject/Soundcaster Sessions/Default Work Unit.wwu index 65c592fa8..957ed9e4e 100644 --- a/Aetheria-Economy_WwiseProject/Soundcaster Sessions/Default Work Unit.wwu +++ b/Aetheria-Economy_WwiseProject/Soundcaster Sessions/Default Work Unit.wwu @@ -177,7 +177,7 @@ - 0.54 + 0.66 @@ -185,7 +185,7 @@ - 0.94 + 0.24 @@ -197,7 +197,7 @@ - 100 + 74 @@ -217,19 +217,19 @@ - 1 + 0.96 - + 0 - 0.71 + 0 - 0.5 + 1 diff --git a/Aetheria.Shared.Unity.csproj b/Aetheria.Shared.Unity.csproj index c9897fb8d..a1178fde1 100644 --- a/Aetheria.Shared.Unity.csproj +++ b/Aetheria.Shared.Unity.csproj @@ -136,8 +136,8 @@ - + @@ -263,9 +263,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -296,6 +293,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Applications/Unity Editors/2020.3.2f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll diff --git a/Ak.Wwise.Api.WAAPI.csproj b/Ak.Wwise.Api.WAAPI.csproj index aa17f2143..d0b9aaab9 100644 --- a/Ak.Wwise.Api.WAAPI.csproj +++ b/Ak.Wwise.Api.WAAPI.csproj @@ -289,9 +289,6 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/Remotion.Linq.dll - - E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll - E:/Projects/Aetheria-Economy/Assets/Plugins/System.Memory.dll @@ -322,6 +319,9 @@ E:/Projects/Aetheria-Economy/Assets/Plugins/System.Runtime.CompilerServices.Unsafe.dll + + E:/Projects/Aetheria-Economy/Assets/Allegorithmic/Plugins/Substance/Substance Engine/Editor/Substance.Editor.dll + E:/Applications/Unity Editors/2020.3.2f1/Editor/Data/MonoBleedingEdge/lib/mono/4.7.1-api/mscorlib.dll diff --git a/Assets/InputDisplayKey.cs b/Assets/InputDisplayKey.cs index e9f64ed03..f3d24d400 100644 --- a/Assets/InputDisplayKey.cs +++ b/Assets/InputDisplayKey.cs @@ -6,8 +6,8 @@ using UnityEngine.UI; public class InputDisplayKey : MonoBehaviour { - public TextMeshProUGUI First; - public TextMeshProUGUI Second; + 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 f89fe65ae..1dbe43078 100644 --- a/Assets/InputDisplayLayout.cs +++ b/Assets/InputDisplayLayout.cs @@ -2,38 +2,296 @@ using System; using System.Collections; using System.Collections.Generic; using System.IO; +using System.Linq; +using MessagePack; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; +using TMPro; using UnityEngine; +using UnityEngine.InputSystem; using UnityEngine.UI; +using UnityEngine.UI.Extensions; +using Unity.Mathematics; +using static Unity.Mathematics.math; public class InputDisplayLayout : MonoBehaviour { + public VerticalLayoutGroup RowContainer; public TextAsset LayoutFile; + public Prototype LabelPrototype; + public Prototype LinePrototype; + //public UILineRendererList LineRenderer; public Prototype RowPrototype; public Prototype RowSpacerPrototype; public int KeySize = 64; + public Color DefaultColor; + public Color HighlightColor; + public float FillBrightness = .5f; + public float FillAlpha; + public float FillMultiplier = .25f; + public float InactiveMultiplier = .333f; + public int TestSteps = 5; + public float TestPadding = 4; + public float BoxLineExpand = -1; + public Color GlobalColor; + public float GlobalHueBuffer = .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 string FullKeyPath(string shortPath) => $"/{shortPath}"; + private string ShortKeyPath(string fullPath) => fullPath.Substring(fullPath.LastIndexOf('/') + 1); 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; + // var keyPress = new InputAction(binding: fullInputPath); + // keyPress.started += context => + // { + // var displayKey = _displayKeys[key]; + // displayKey.Outline.color = HighlightColor; + // var fillColor = HighlightColor; + // fillColor *= FillMultiplier; + // fillColor.a = FillAlpha; + // displayKey.Fill.color = fillColor; + // }; + // keyPress.canceled += context => + // { + // var displayKey = _displayKeys[key]; + // displayKey.Outline.color = DefaultColor; + // var fillColor = DefaultColor; + // fillColor *= FillMultiplier; + // fillColor.a = FillAlpha; + // 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 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 line = LinePrototype.Instantiate(); + line.color = _actionColors[action]; + line.Points = new[] { keyPoint, labelPoint }; + } + + //StartCoroutine(AssociateInputKeys(_inputLayout)); + } + + private Vector2 FindLabelPosition(RectTransform key, RectTransform label, Vector2 dir) + { + var keyRect = key.ScreenSpaceRect(); + var labelRect = label.ScreenSpaceRect(TestPadding); + var localRects = Overlap(key.ScreenSpaceRect(TestSteps * KeySize)); + var keyCenter = keyRect.center; + for (int dist = KeySize; dist < TestSteps * 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 testRect = new Rect(testPos - labelRect.size / 2, labelRect.size); + if(!localRects.Any(r => r.Overlaps(testRect))) + { + _reservedRects.Add(testRect); + return testPos; + } + } + } + } + return Vector2.zero; + } + + private Rect[] Overlap(Rect rect) => _reservedRects.Where(r => r.Overlaps(rect)).ToArray(); + + public void DisplayLayout(InputLayout layout) + { + foreach (var row in layout.Rows) + { + if (row is InputLayoutKeyRow keyRow) + { + var displayRow = RowPrototype.Instantiate(); + _layoutGroups.Add(displayRow.LayoutGroup); + foreach (var column in keyRow.Columns) + { + if (column is InputLayoutColumnSpacer) + { + displayRow.KeySpacerPrototype.Instantiate().preferredWidth = KeySize * column.Width; + } + else if (column is InputLayoutKey) + { + var displayKey = displayRow.KeyPrototype.Instantiate(); + displayKey.LayoutElement.preferredHeight = KeySize; + 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); + + if (column is InputLayoutBindableKey key) + { + _displayKeys[key] = displayKey; + displayKey.MainLabel.text = key.MainLabel; + displayKey.AltLabel.text = key.AltLabel; + + if (column is InputLayoutMultiRowKey multiRowKey) + { + displayKey.Outline.rectTransform.anchorMin = + displayKey.MainLabel.rectTransform.anchorMin = + displayKey.AltLabel.rectTransform.anchorMin = + displayKey.Fill.rectTransform.anchorMin = Vector2.down * (multiRowKey.Height - 1); + } + } + else + { + fillColor.a *= InactiveMultiplier; + displayKey.MainLabel.text = ""; + displayKey.AltLabel.text = ""; + } + displayKey.Fill.color = fillColor; + } + else + { + throw new ArgumentOutOfRangeException(nameof(column)); + } + } + } + else if (row is InputLayoutRowSpacer rowSpacer) + { + RowSpacerPrototype.Instantiate().preferredHeight = KeySize * rowSpacer.Height; + } + else + { + throw new ArgumentOutOfRangeException(nameof(row)); + } + } + } + + public InputLayout ParseJson(string layout) + { + var rows = new List(); var nextWidth = 1f; - var nextHeight = 1f; - var reader = new JsonTextReader(new StringReader(LayoutFile.text)); + var nextHeight = 1; + var reader = new JsonTextReader(new StringReader(layout)); + reader.Read(); if (reader.TokenType != JsonToken.StartArray) - { - Debug.Log($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}"); - return; - } + throw new JsonReaderException($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}, expected: StartArray, received: {Enum.GetName(typeof(JsonToken), reader.TokenType)}"); + while(reader.Read() && reader.TokenType != JsonToken.EndArray) { if (reader.TokenType != JsonToken.StartArray) - { - Debug.Log($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}"); - return; - } + throw new JsonReaderException($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}, expected: StartArray, received: {Enum.GetName(typeof(JsonToken), reader.TokenType)}"); - var row = RowPrototype.Instantiate(); + var row = new InputLayoutKeyRow(); + var columns = new List(); while (reader.Read() && reader.TokenType != JsonToken.EndArray) { @@ -49,59 +307,92 @@ public class InputDisplayLayout : MonoBehaviour nextWidth = (float) (reader.ReadAsDouble() ?? 1.0); break; case "h": - nextHeight = (float) (reader.ReadAsDouble() ?? 1.0); + nextHeight = reader.ReadAsInt32() ?? 1; break; case "y": - RowSpacerPrototype.Instantiate().preferredHeight = KeySize * (float) (reader.ReadAsDouble() ?? 0.0); - row.transform.SetAsLastSibling(); + rows.Add(new InputLayoutRowSpacer{Height = (float) (reader.ReadAsDouble() ?? 0.0)}); break; case "x": - row.KeySpacerPrototype.Instantiate().preferredWidth = KeySize * (float) (reader.ReadAsDouble() ?? 0.0); + columns.Add(new InputLayoutColumnSpacer{Width = (float) (reader.ReadAsDouble() ?? 0.0)}); break; } } break; case JsonToken.String: - var key = row.KeyPrototype.Instantiate(); + InputLayoutKey key; var v = reader.Value.ToString().Trim(); if (!string.IsNullOrEmpty(v)) { var labels = v.Split('\n'); - if (labels.Length == 2) - { - key.First.text = labels[1]; - key.Second.text = labels[0]; - } - else - { - key.First.text = v; - key.Second.text = ""; - } + key = nextHeight != 1 ? new InputLayoutMultiRowKey {Height = nextHeight} : new InputLayoutBindableKey(); + nextHeight = 1; + ((InputLayoutBindableKey) key).MainLabel = labels.Length == 2 ? labels[1] : v; + ((InputLayoutBindableKey) key).AltLabel = labels.Length == 2 ? labels[0] : ""; } else - { - key.First.text = ""; - key.Second.text = ""; - } + key = new InputLayoutKey(); - key.LayoutElement.preferredHeight = KeySize; - key.LayoutElement.preferredWidth = KeySize * nextWidth; + key.Width = nextWidth; + columns.Add(key); nextWidth = 1f; - if (Math.Abs(nextHeight - 1f) > .01f) - { - key.Outline.rectTransform.anchorMin = - key.First.rectTransform.anchorMin = - key.Second.rectTransform.anchorMin = - key.Fill.rectTransform.anchorMin = Vector2.down * (nextHeight-1); - } - nextHeight = 1f; break; default: - Debug.Log($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}"); - return; + throw new JsonReaderException($"Unexpected JSON format in line {reader.LineNumber}:{reader.LinePosition}"); + } + } + + row.Columns = columns.ToArray(); + rows.Add(row); + } + + return new InputLayout {Rows = rows.ToArray()}; + } + + private IEnumerator AssociateInputKeys(InputLayout layout) + { + var path = ""; + var keyPress = new InputAction(binding: "//