From 0e3595240b0efd13fc63402cdb0d6da53eb05696 Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Sun, 10 Dec 2023 22:16:10 +0900 Subject: [PATCH 01/27] Unity proc supports ".vrma"-only motion list --- .../WordToMotion/V2/WordToMotionPresenter.cs | 34 ++++++++++++------- .../Scripts/Interprocess/Model/VmmQueries.cs | 2 +- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/AvatarControl/WordToMotion/V2/WordToMotionPresenter.cs b/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/AvatarControl/WordToMotion/V2/WordToMotionPresenter.cs index 569046d36..6be7e0a38 100644 --- a/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/AvatarControl/WordToMotion/V2/WordToMotionPresenter.cs +++ b/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/AvatarControl/WordToMotion/V2/WordToMotionPresenter.cs @@ -68,19 +68,10 @@ public override void Initialize() // VmmCommands.RequestCustomMotionDoctor, // _ => { } // ); - + _receiver.AssignQueryHandler( VmmQueries.GetAvailableCustomMotionClipNames, - q => - { - //カスタムモーションと呼ばれるものがvmm_motionとvrmaの2種類ある - q.Result = string.Join("\t", - _customMotionRepository - .LoadAvailableCustomMotionNames() - .Concat(_vrmaRepository.GetAvailableMotionNames()) - ); - Debug.Log("Get Available CustomMotion Clip Names, result = " + q.Result); - }); + SetAvailableMotionClipNames); //リクエストは等価に扱う && 頻度は制御する、という話 _sources @@ -115,7 +106,7 @@ public override void Initialize() _vrmaRepository.Initialize(); } - + private void SetWordToMotionInputType(int deviceType) { var type = (SourceType) deviceType; @@ -160,5 +151,24 @@ private void ReceiveWordToMotionPreviewInfo(string json) LogOutput.Instance.Write(ex); } } + + private void SetAvailableMotionClipNames(ReceivedQuery q) + { + //カスタムモーションと呼ばれるものがvmm_motionとvrmaの2種類あるが、引数によってはvrmaのみを返却する + var vrmaOnly = q.ToBoolean(); + if (vrmaOnly) + { + q.Result = string.Join("\t", _vrmaRepository.GetAvailableMotionNames()); + } + else + { + q.Result = string.Join("\t", + _customMotionRepository + .LoadAvailableCustomMotionNames() + .Concat(_vrmaRepository.GetAvailableMotionNames()) + ); + } + Debug.Log("Get Available CustomMotion Clip Names, result = " + q.Result); + } } } diff --git a/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/Interprocess/Model/VmmQueries.cs b/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/Interprocess/Model/VmmQueries.cs index 8866c6ff2..6c590c552 100644 --- a/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/Interprocess/Model/VmmQueries.cs +++ b/VMagicMirror/Assets/Baku/VMagicMirror/Scripts/Interprocess/Model/VmmQueries.cs @@ -16,7 +16,7 @@ public static class VmmQueries public const string GetQualitySettingsInfo = nameof(GetQualitySettingsInfo); public const string ApplyDefaultImageQuality = nameof(ApplyDefaultImageQuality); - // Word to Motion + // Word to Motion / GameInput public const string GetAvailableCustomMotionClipNames = nameof(GetAvailableCustomMotionClipNames); } } From 7f8aa191fe0d2a42bf90f3a8bd094acf69f91de9 Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Sun, 10 Dec 2023 22:16:58 +0900 Subject: [PATCH 02/27] in WPF custom motion list is stored 2 way --- .../Model/InterProcess/Core/MessageFactory.cs | 4 ++-- .../InterProcess/Util/CustomMotionList.cs | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/WPF/VMagicMirrorConfig/Model/InterProcess/Core/MessageFactory.cs b/WPF/VMagicMirrorConfig/Model/InterProcess/Core/MessageFactory.cs index 57d863293..9c97ca64d 100644 --- a/WPF/VMagicMirrorConfig/Model/InterProcess/Core/MessageFactory.cs +++ b/WPF/VMagicMirrorConfig/Model/InterProcess/Core/MessageFactory.cs @@ -307,10 +307,10 @@ private static Message WithArg(int content, [CallerMemberName] string command = public Message RequestCustomMotionDoctor() => NoArg(); /// - /// Query + /// Query : 引数をtrueにすると .vrma 形式になってるものだけ返却してくれる /// /// - public Message GetAvailableCustomMotionClipNames() => NoArg(); + public Message GetAvailableCustomMotionClipNames(bool vrmaOnly) => WithArg(vrmaOnly); #endregion diff --git a/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs b/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs index 9f110409d..1a6deb23a 100644 --- a/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs +++ b/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs @@ -12,6 +12,7 @@ public CustomMotionList(IMessageSender sender) { _sender = sender; CustomMotionClipNames = new ReadOnlyObservableCollection(_customMotionClipNames); + VrmaCustomMotionClipNames = new ReadOnlyObservableCollection(_vrmaCustomMotionClipNames); } private readonly IMessageSender _sender; @@ -19,18 +20,29 @@ public CustomMotionList(IMessageSender sender) private readonly ObservableCollection _customMotionClipNames = new ObservableCollection(); public ReadOnlyObservableCollection CustomMotionClipNames { get; } + private readonly ObservableCollection _vrmaCustomMotionClipNames = new ObservableCollection(); + public ReadOnlyObservableCollection VrmaCustomMotionClipNames { get; } + public async Task InitializeCustomMotionClipNamesAsync() { - var clipNames = await GetAvailableCustomMotionClipNamesAsync(); + //NOTE: 2回取得するのは若干もっさりするが、アプリ起動後の1回だけなので許容しておく + var clipNames = await GetCustomMotionClipNamesAsync(false); foreach (var name in clipNames) { _customMotionClipNames.Add(name); } + + var vrmaClipNames = await GetCustomMotionClipNamesAsync(true); + foreach (var name in vrmaClipNames) + { + _vrmaCustomMotionClipNames.Add(name); + } } - private async Task GetAvailableCustomMotionClipNamesAsync() + private async Task GetCustomMotionClipNamesAsync(bool vrmaOnly) { - var rawClipNames = await _sender.QueryMessageAsync(MessageFactory.Instance.GetAvailableCustomMotionClipNames()); + var rawClipNames = await _sender.QueryMessageAsync( + MessageFactory.Instance.GetAvailableCustomMotionClipNames(vrmaOnly)); return rawClipNames.Split('\t'); } } From 94f9f826a8b1cc88158cec85a6e69dee48ddf77c Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Sun, 10 Dec 2023 22:26:46 +0900 Subject: [PATCH 03/27] Add support or vrma based gamepad / click / key inputs --- .../Model/Entity/GameInputSetting.cs | 63 ++++- .../Model/GameInput/GameInputActionKey.cs | 44 ++++ .../SettingModel/GameInputSettingModel.cs | 225 ++++++++++++++---- .../GameInputActionKeyToStringConverter.cs | 37 +++ .../GameInput/GameInputKeyAssignItem.xaml | 9 +- .../View/GameInput/KeyAssignPanel.xaml | 9 +- ...GameInputKeyboardKeyAssignItemViewModel.cs | 17 +- .../ViewModel/KeyAssign/KeyAssignViewModel.cs | 213 +++++++++++------ 8 files changed, 488 insertions(+), 129 deletions(-) create mode 100644 WPF/VMagicMirrorConfig/Model/GameInput/GameInputActionKey.cs create mode 100644 WPF/VMagicMirrorConfig/View/Code/Converter/GameInputActionKeyToStringConverter.cs diff --git a/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs b/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs index adcdedd65..3862c617b 100644 --- a/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs +++ b/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Windows.Input; namespace Baku.VMagicMirrorConfig @@ -22,7 +23,8 @@ public enum GameInputStickAction public enum GameInputButtonAction { - None, + Custom = -1, + None = 0, Jump, Crouch, Run, @@ -65,7 +67,21 @@ public enum GameInputMouseButton Middle, } + /// + /// のカスタムの詳細を記述するクラス + /// + public class GameInputCustomAction + { + //NOTE: string 1つなのにclass化するのはループとかマスクとかIKどうするとか設定したい可能性に配慮するため + public string CustomKey { get; set; } = ""; + } + public class KeyboardKeyWithGameInputCustomAction + { + public GameInputCustomAction CustomAction { get; set; } = new(); + public string KeyCode { get; set; } = ""; + } + //Entityに移動していいんでは public class GameInputGamepadKeyAssign { @@ -83,6 +99,34 @@ public class GameInputGamepadKeyAssign public GameInputButtonAction ButtonView { get; set; } public GameInputButtonAction ButtonMenu { get; set; } + public GameInputCustomAction CustomButtonA { get; set; } = new(); + public GameInputCustomAction CustomButtonB { get; set; } = new(); + public GameInputCustomAction CustomButtonX { get; set; } = new(); + public GameInputCustomAction CustomButtonY { get; set; } = new(); + + public GameInputCustomAction CustomButtonLButton { get; set; } = new(); + public GameInputCustomAction CustomButtonLTrigger { get; set; } = new(); + public GameInputCustomAction CustomButtonRButton { get; set; } = new(); + public GameInputCustomAction CustomButtonRTrigger { get; set; } = new(); + + public GameInputCustomAction CustomButtonView { get; set; } = new(); + public GameInputCustomAction CustomButtonMenu { get; set; } = new(); + + public GameInputActionKey ButtonAKey => new(ButtonA, CustomButtonA); + public GameInputActionKey ButtonBKey => new(ButtonB, CustomButtonB); + public GameInputActionKey ButtonXKey => new(ButtonX, CustomButtonX); + public GameInputActionKey ButtonYKey => new(ButtonY, CustomButtonY); + + public GameInputActionKey ButtonLButtonKey => new(ButtonLButton, CustomButtonLButton); + public GameInputActionKey ButtonLTriggerKey => new(ButtonLTrigger, CustomButtonLTrigger); + public GameInputActionKey ButtonRButtonKey => new(ButtonRButton, CustomButtonRButton); + public GameInputActionKey ButtonRTriggerKey => new(ButtonRTrigger, CustomButtonRTrigger); + + public GameInputActionKey ButtonViewKey => new(ButtonView, CustomButtonView); + public GameInputActionKey ButtonMenuKey => new(ButtonMenu, CustomButtonMenu); + + + public GameInputStickAction DPadLeft { get; set; } public GameInputStickAction StickLeft { get; set; } = GameInputStickAction.Move; public GameInputStickAction StickRight { get; set; } = GameInputStickAction.LookAround; @@ -97,6 +141,13 @@ public class GameInputKeyboardKeyAssign public GameInputButtonAction LeftClick { get; set; } public GameInputButtonAction RightClick { get; set; } public GameInputButtonAction MiddleClick { get; set; } + public GameInputCustomAction CustomLeftClick { get; set; } = new(); + public GameInputCustomAction CustomRightClick { get; set; } = new(); + public GameInputCustomAction CustomMiddleClick { get; set; } = new(); + public GameInputActionKey LeftClickKey => new(LeftClick, CustomLeftClick); + public GameInputActionKey RightClickKey => new(RightClick, CustomRightClick); + public GameInputActionKey MiddleClickKey => new(MiddleClick, CustomMiddleClick); + //よくあるやつなので + このキーアサインでは補助キーを無視したいのでShiftも特別扱い public bool UseWasdMove { get; set; } = true; @@ -112,6 +163,9 @@ public class GameInputKeyboardKeyAssign public string TriggerKeyCode { get; set; } = ""; public string PunchKeyCode { get; set; } = ""; + public KeyboardKeyWithGameInputCustomAction[] CustomActions { get; set; } + = Array.Empty(); + public static GameInputKeyboardKeyAssign LoadDefault() => new(); //Unityに投げつける用に前処理したデータを生成する @@ -134,6 +188,13 @@ public GameInputKeyboardKeyAssign GetKeyCodeTranslatedData() result.CrouchKeyCode = TranslateKeyCode(CrouchKeyCode); result.TriggerKeyCode = TranslateKeyCode(TriggerKeyCode); result.PunchKeyCode = TranslateKeyCode(PunchKeyCode); + result.CustomActions = CustomActions + .Select(a => new KeyboardKeyWithGameInputCustomAction() + { + KeyCode = TranslateKeyCode(a.KeyCode), + CustomAction = a.CustomAction, + }) + .ToArray(); return result; } diff --git a/WPF/VMagicMirrorConfig/Model/GameInput/GameInputActionKey.cs b/WPF/VMagicMirrorConfig/Model/GameInput/GameInputActionKey.cs new file mode 100644 index 000000000..71aef3b10 --- /dev/null +++ b/WPF/VMagicMirrorConfig/Model/GameInput/GameInputActionKey.cs @@ -0,0 +1,44 @@ +using System; + +namespace Baku.VMagicMirrorConfig +{ + public readonly struct GameInputActionKey : IEquatable + { + + public GameInputActionKey(GameInputButtonAction actionType, GameInputCustomAction customAction) + { + ActionType = actionType; + CustomActionKey = actionType is GameInputButtonAction.Custom ? "" : customAction.CustomKey; + } + + private GameInputActionKey(GameInputButtonAction actionType, string key) + { + ActionType = actionType; + CustomActionKey = key; + } + + //NOTE: データの期待としてCustomじゃないActionに対するCustomAction.CustomKeyは必ず空…というのを想定している + public GameInputButtonAction ActionType { get; } + public string CustomActionKey { get; } + public GameInputCustomAction CustomAction => new() { CustomKey = CustomActionKey }; + + + public bool Equals(GameInputActionKey other) + { + return + ActionType == other.ActionType && + CustomActionKey == other.CustomActionKey; + } + + public override bool Equals(object? obj) => obj is GameInputActionKey other && Equals(other); + + public override int GetHashCode() => HashCode.Combine(ActionType, CustomActionKey); + + public static GameInputActionKey BuiltIn(GameInputButtonAction action) + => new(action, new GameInputCustomAction()); + public static GameInputActionKey Custom(string key) + => new(GameInputButtonAction.Custom, key); + + public static GameInputActionKey Empty { get; } = new(GameInputButtonAction.None, ""); + } +} diff --git a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs index 9713839f6..c68c2b1aa 100644 --- a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs +++ b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs @@ -1,19 +1,25 @@ using Newtonsoft.Json; using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using System.Text; namespace Baku.VMagicMirrorConfig { class GameInputSettingModel { - public GameInputSettingModel() : this(ModelResolver.Instance.Resolve()) + public GameInputSettingModel() : this( + ModelResolver.Instance.Resolve(), + ModelResolver.Instance.Resolve() + ) { } - public GameInputSettingModel(IMessageSender sender) + public GameInputSettingModel(IMessageSender sender, CustomMotionList customMotionList) { _sender = sender; + _motionList = customMotionList; var setting = GameInputSetting.Default; GamepadKeyAssign = setting.GamepadKeyAssign; @@ -63,6 +69,7 @@ public GameInputSettingModel(IMessageSender sender) } private readonly IMessageSender _sender; + private readonly CustomMotionList _motionList; public event EventHandler? GamepadKeyAssignUpdated; public event EventHandler? KeyboardKeyAssignUpdated; @@ -137,41 +144,72 @@ public void SaveSetting(string filePath) public void LoadSettingFromDefaultFile() => LoadSetting(SpecialFilePath.GameInputDefaultFilePath); public void SaveSettingToDefaultFile() => SaveSetting(SpecialFilePath.GameInputDefaultFilePath); - public void SetGamepadButtonAction(GameInputGamepadButton button, GameInputButtonAction action) + public void SetGamepadButtonAction(GameInputGamepadButton button, GameInputActionKey actionKey) { - var current = button switch + var currentKey = button switch { - GameInputGamepadButton.A => GamepadKeyAssign.ButtonA, - GameInputGamepadButton.B => GamepadKeyAssign.ButtonB, - GameInputGamepadButton.X => GamepadKeyAssign.ButtonX, - GameInputGamepadButton.Y => GamepadKeyAssign.ButtonY, - GameInputGamepadButton.LB => GamepadKeyAssign.ButtonLButton, - GameInputGamepadButton.RB => GamepadKeyAssign.ButtonRButton, - GameInputGamepadButton.LTrigger => GamepadKeyAssign.ButtonLTrigger, - GameInputGamepadButton.RTrigger => GamepadKeyAssign.ButtonRTrigger, - GameInputGamepadButton.View => GamepadKeyAssign.ButtonView, - GameInputGamepadButton.Menu => GamepadKeyAssign.ButtonMenu, - _ => GameInputButtonAction.None, + GameInputGamepadButton.A => GamepadKeyAssign.ButtonAKey, + GameInputGamepadButton.B => GamepadKeyAssign.ButtonBKey, + GameInputGamepadButton.X => GamepadKeyAssign.ButtonXKey, + GameInputGamepadButton.Y => GamepadKeyAssign.ButtonYKey, + GameInputGamepadButton.LB => GamepadKeyAssign.ButtonLButtonKey, + GameInputGamepadButton.RB => GamepadKeyAssign.ButtonRButtonKey, + GameInputGamepadButton.LTrigger => GamepadKeyAssign.ButtonLTriggerKey, + GameInputGamepadButton.RTrigger => GamepadKeyAssign.ButtonRTriggerKey, + GameInputGamepadButton.View => GamepadKeyAssign.ButtonViewKey, + GameInputGamepadButton.Menu => GamepadKeyAssign.ButtonMenuKey, + _ => GameInputActionKey.Empty, }; - if (action == current) + if (actionKey.Equals(currentKey)) { return; } switch(button) { - case GameInputGamepadButton.A: GamepadKeyAssign.ButtonA = action; break; - case GameInputGamepadButton.B: GamepadKeyAssign.ButtonB = action; break; - case GameInputGamepadButton.X: GamepadKeyAssign.ButtonX = action; break; - case GameInputGamepadButton.Y: GamepadKeyAssign.ButtonY = action; break; - case GameInputGamepadButton.LB: GamepadKeyAssign.ButtonLButton = action; break; - case GameInputGamepadButton.RB: GamepadKeyAssign.ButtonRButton = action; break; - case GameInputGamepadButton.LTrigger: GamepadKeyAssign.ButtonLTrigger = action; break; - case GameInputGamepadButton.RTrigger: GamepadKeyAssign.ButtonRTrigger = action; break; - case GameInputGamepadButton.View: GamepadKeyAssign.ButtonView = action; break; - case GameInputGamepadButton.Menu: GamepadKeyAssign.ButtonMenu = action; break; - default: return; + case GameInputGamepadButton.A: + GamepadKeyAssign.ButtonA = actionKey.ActionType; + GamepadKeyAssign.CustomButtonA = actionKey.CustomAction; + break; + case GameInputGamepadButton.B: + GamepadKeyAssign.ButtonB = actionKey.ActionType; + GamepadKeyAssign.CustomButtonB = actionKey.CustomAction; + break; + case GameInputGamepadButton.X: + GamepadKeyAssign.ButtonX = actionKey.ActionType; + GamepadKeyAssign.CustomButtonX = actionKey.CustomAction; + break; + case GameInputGamepadButton.Y: + GamepadKeyAssign.ButtonY = actionKey.ActionType; + GamepadKeyAssign.CustomButtonY = actionKey.CustomAction; + break; + case GameInputGamepadButton.LB: + GamepadKeyAssign.ButtonLButton = actionKey.ActionType; + GamepadKeyAssign.CustomButtonLButton = actionKey.CustomAction; + break; + case GameInputGamepadButton.RB: + GamepadKeyAssign.ButtonRButton = actionKey.ActionType; + GamepadKeyAssign.CustomButtonRButton = actionKey.CustomAction; + break; + case GameInputGamepadButton.LTrigger: + GamepadKeyAssign.ButtonLTrigger = actionKey.ActionType; + GamepadKeyAssign.CustomButtonLTrigger = actionKey.CustomAction; + break; + case GameInputGamepadButton.RTrigger: + GamepadKeyAssign.ButtonRTrigger = actionKey.ActionType; + GamepadKeyAssign.CustomButtonRTrigger = actionKey.CustomAction; + break; + case GameInputGamepadButton.View: + GamepadKeyAssign.ButtonView = actionKey.ActionType; + GamepadKeyAssign.CustomButtonView = actionKey.CustomAction; + break; + case GameInputGamepadButton.Menu: + GamepadKeyAssign.ButtonMenu = actionKey.ActionType; + GamepadKeyAssign.CustomButtonMenu = actionKey.CustomAction; + break; + default: + return; } SendGamepadKeyAssign(); @@ -205,42 +243,52 @@ public void SetGamepadStickAction(GameInputGamepadStick stick, GameInputStickAct GamepadKeyAssignUpdated?.Invoke(this, new GamepadKeyAssignUpdateEventArgs(GamepadKeyAssign)); } - public void SetClickAction(GameInputMouseButton button, GameInputButtonAction action) + public void SetClickAction(GameInputMouseButton button, GameInputActionKey actionKey) { var current = button switch { - GameInputMouseButton.Left => KeyboardKeyAssign.LeftClick, - GameInputMouseButton.Right => KeyboardKeyAssign.RightClick, - GameInputMouseButton.Middle => KeyboardKeyAssign.MiddleClick, - _ => GameInputButtonAction.None, + GameInputMouseButton.Left => KeyboardKeyAssign.LeftClickKey, + GameInputMouseButton.Right => KeyboardKeyAssign.RightClickKey, + GameInputMouseButton.Middle => KeyboardKeyAssign.MiddleClickKey, + _ => GameInputActionKey.Empty, }; - if (action == current) + if (actionKey.Equals(current)) { return; } switch (button) { - case GameInputMouseButton.Left: KeyboardKeyAssign.LeftClick = action; break; - case GameInputMouseButton.Right: KeyboardKeyAssign.RightClick = action; break; - case GameInputMouseButton.Middle: KeyboardKeyAssign.MiddleClick = action; break; + case GameInputMouseButton.Left: + KeyboardKeyAssign.LeftClick = actionKey.ActionType; + KeyboardKeyAssign.CustomLeftClick = actionKey.CustomAction; + break; + case GameInputMouseButton.Right: + KeyboardKeyAssign.RightClick = actionKey.ActionType; + KeyboardKeyAssign.CustomRightClick = actionKey.CustomAction; + break; + case GameInputMouseButton.Middle: + KeyboardKeyAssign.MiddleClick = actionKey.ActionType; + KeyboardKeyAssign.CustomMiddleClick = actionKey.CustomAction; + break; default: return; } SendKeyboardKeyAssign(); - KeyboardKeyAssignUpdated?.Invoke(this, new KeyboardKeyAssignUpdateEventArgs(KeyboardKeyAssign)); + KeyboardKeyAssignUpdated?.Invoke(this, new(KeyboardKeyAssign)); } - public void SetKeyAction(GameInputButtonAction action, string key) + public void SetKeyAction(GameInputActionKey actionKey, string key) { - var current = action switch + var current = actionKey.ActionType switch { GameInputButtonAction.Jump => KeyboardKeyAssign.JumpKeyCode, GameInputButtonAction.Crouch => KeyboardKeyAssign.CrouchKeyCode, GameInputButtonAction.Run => KeyboardKeyAssign.RunKeyCode, GameInputButtonAction.Trigger => KeyboardKeyAssign.TriggerKeyCode, GameInputButtonAction.Punch => KeyboardKeyAssign.PunchKeyCode, + GameInputButtonAction.Custom => FindKeyCodeOfCustomAction(actionKey), _ => "", }; @@ -249,22 +297,117 @@ public void SetKeyAction(GameInputButtonAction action, string key) return; } - switch (action) + switch (actionKey.ActionType) { case GameInputButtonAction.Jump: KeyboardKeyAssign.JumpKeyCode = key; break; case GameInputButtonAction.Crouch: KeyboardKeyAssign.CrouchKeyCode = key; break; case GameInputButtonAction.Run: KeyboardKeyAssign.RunKeyCode = key; break; case GameInputButtonAction.Trigger: KeyboardKeyAssign.TriggerKeyCode = key; break; case GameInputButtonAction.Punch: KeyboardKeyAssign.PunchKeyCode = key; break; + case GameInputButtonAction.Custom: + var target = KeyboardKeyAssign + .CustomActions + .FirstOrDefault(a => a.CustomAction.CustomKey == actionKey.CustomActionKey); + if (target == null) + { + return; + } + + target.KeyCode = key; + break; default: return; } SendKeyboardKeyAssign(); - KeyboardKeyAssignUpdated?.Invoke(this, new KeyboardKeyAssignUpdateEventArgs(KeyboardKeyAssign)); + KeyboardKeyAssignUpdated?.Invoke(this, new(KeyboardKeyAssign)); + } + + //この関数が呼ばれると、カスタムアクション用のキーボード設定に過不足があった場合の内容が修正される。 + // - 指定した一覧にはあるのに設定として保持してない -> キーアサインがない状態で追加 + // - 指定した一覧に入ってないものが設定に含まれる -> 削除 + public void RefreshCustomActionKeys(GameInputActionKey[] actionKeys) + { + var currentKeys = KeyboardKeyAssign + .CustomActions + .Select(a => GameInputActionKey.Custom(a.CustomAction.CustomKey)) + .ToHashSet(); + + if (currentKeys.SetEquals(actionKeys)) + { + return; + } + + var resultCustomActions = new KeyboardKeyWithGameInputCustomAction[actionKeys.Length]; + for (var i = 0; i < resultCustomActions.Length; i++) + { + var key = actionKeys[i]; + resultCustomActions[i] = new KeyboardKeyWithGameInputCustomAction() + { + CustomAction = new GameInputCustomAction() { CustomKey = key.CustomActionKey }, + KeyCode = FindKeyCodeOfCustomAction(key), + }; + } + + KeyboardKeyAssign.CustomActions = resultCustomActions.ToArray(); + SendKeyboardKeyAssign(); + KeyboardKeyAssignUpdated?.Invoke(this, new(KeyboardKeyAssign)); } + public void ResetToDefault() => ApplySetting(GameInputSetting.Default); + /// + /// NOTE: BuiltInアクションに対しても定義できるが、直近で必要ないため使っていない + /// + /// + /// + public string FindKeyCodeOfCustomAction(GameInputActionKey action) + { + var item = KeyboardKeyAssign.CustomActions + .FirstOrDefault(a => a.CustomAction.Equals(action)); + + if (item != null) + { + return item.KeyCode; + } + else + { + return ""; + } + } + + public GameInputActionKey[] LoadCustomActionKeys() + { + return _motionList.VrmaCustomMotionClipNames + .Select(GameInputActionKey.Custom) + .ToArray(); + } + + //NOTE: + // 起動直後でcustomMotionListが空の状態で呼ぶと .vrma を含まない結果が戻ってしまうが、 + // この問題は特にケアしない(ゲーム入力の設定ウィンドウが開くまでは呼ばれないはずなので) + public GameInputActionKey[] LoadAvailableActionKeys() + { + + var result = new List() + { + GameInputActionKey.BuiltIn(GameInputButtonAction.None), + GameInputActionKey.BuiltIn(GameInputButtonAction.Jump), + GameInputActionKey.BuiltIn(GameInputButtonAction.Crouch), + GameInputActionKey.BuiltIn(GameInputButtonAction.Run), + GameInputActionKey.BuiltIn(GameInputButtonAction.Trigger), + GameInputActionKey.BuiltIn(GameInputButtonAction.Punch), + }; + + foreach (var vrmaMotionKey in _motionList.VrmaCustomMotionClipNames) + { + + result.Add(GameInputActionKey.Custom(vrmaMotionKey)); + } + + return result.ToArray(); + } + private GameInputSetting BuildCurrentSetting() { diff --git a/WPF/VMagicMirrorConfig/View/Code/Converter/GameInputActionKeyToStringConverter.cs b/WPF/VMagicMirrorConfig/View/Code/Converter/GameInputActionKeyToStringConverter.cs new file mode 100644 index 000000000..1a6a27ce1 --- /dev/null +++ b/WPF/VMagicMirrorConfig/View/Code/Converter/GameInputActionKeyToStringConverter.cs @@ -0,0 +1,37 @@ +using System; +using System.Globalization; +using System.Windows.Data; + +namespace Baku.VMagicMirrorConfig.View +{ + public class GameInputActionKeyToStringConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is not GameInputActionKey key) + { + return Binding.DoNothing; + } + + // - customの場合は翻訳されない + // - customの場合は"vrma_"みたいな接頭辞がついてるはずなので、ビルトインのものとは区別がつく想定 + switch (key.ActionType) + { + case GameInputButtonAction.None: return LocalizedString.GetString("GameInputKeyAssign_Action_None"); + case GameInputButtonAction.Jump: return LocalizedString.GetString("GameInputKeyAssign_ButtonAction_Jump"); + case GameInputButtonAction.Crouch: return LocalizedString.GetString("GameInputKeyAssign_ButtonAction_Crouch"); + case GameInputButtonAction.Run: return LocalizedString.GetString("GameInputKeyAssign_ButtonAction_Run"); + case GameInputButtonAction.Trigger: return LocalizedString.GetString("GameInputKeyAssign_ButtonAction_Trigger"); + case GameInputButtonAction.Punch: return LocalizedString.GetString("GameInputKeyAssign_ButtonAction_Punch"); + case GameInputButtonAction.Custom: return key.CustomActionKey; + } + + //通常ここには到達しない + return Binding.DoNothing; + } + + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + => Binding.DoNothing; + } +} diff --git a/WPF/VMagicMirrorConfig/View/GameInput/GameInputKeyAssignItem.xaml b/WPF/VMagicMirrorConfig/View/GameInput/GameInputKeyAssignItem.xaml index 65724b520..7cd064509 100644 --- a/WPF/VMagicMirrorConfig/View/GameInput/GameInputKeyAssignItem.xaml +++ b/WPF/VMagicMirrorConfig/View/GameInput/GameInputKeyAssignItem.xaml @@ -10,14 +10,19 @@ mc:Ignorable="d" d:DataContext="{d:DesignInstance vm:GameInputKeyAssignItemViewModel}" d:DesignHeight="40" d:DesignWidth="450"> + + + - - + + - + @@ -208,31 +215,31 @@ /> @@ -291,42 +298,42 @@ /> @@ -428,17 +435,17 @@ /> From daa9d6aa6b5c9263e16117e38d3c30524de6ed13 Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Wed, 20 Dec 2023 22:52:00 +0900 Subject: [PATCH 13/27] Fix: check custom action key list content on initialize --- .../SettingModel/GameInputSettingModel.cs | 24 ++++++++++++++++--- .../ViewModel/MainWindowViewModel.cs | 2 +- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs index c68c2b1aa..edee68194 100644 --- a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs +++ b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs @@ -65,11 +65,11 @@ public GameInputSettingModel(IMessageSender sender, CustomMotionList customMotio KeyboardKeyAssign.UseSpaceJump = v; SendMessage(factory.UseSpaceJumpGameInput(v)); }); - } private readonly IMessageSender _sender; private readonly CustomMotionList _motionList; + private GameInputActionKey[] _customActionKeys = Array.Empty(); public event EventHandler? GamepadKeyAssignUpdated; public event EventHandler? KeyboardKeyAssignUpdated; @@ -124,6 +124,13 @@ public void LoadSetting(string filePath) public void SaveSetting(string filePath) { + //NOTE: 起動直後にアプリケーションが終了する場合ここを通る + //たぶん問題ないはずだが、カスタムモーションの登録状況に責任を持ちにくいので止めておく感じにしている + if (!_motionList.IsInitialized) + { + return; + } + var serializer = new JsonSerializer(); var sb = new StringBuilder(); @@ -141,7 +148,13 @@ public void SaveSetting(string filePath) } } - public void LoadSettingFromDefaultFile() => LoadSetting(SpecialFilePath.GameInputDefaultFilePath); + public async void InitializeAsync() + { + LoadSetting(SpecialFilePath.GameInputDefaultFilePath); + await _motionList.WaitCustomMotionsCompletedAsync(); + CheckCustomActionKeys(); + } + public void SaveSettingToDefaultFile() => SaveSetting(SpecialFilePath.GameInputDefaultFilePath); public void SetGamepadButtonAction(GameInputGamepadButton button, GameInputActionKey actionKey) @@ -325,8 +338,10 @@ public void SetKeyAction(GameInputActionKey actionKey, string key) //この関数が呼ばれると、カスタムアクション用のキーボード設定に過不足があった場合の内容が修正される。 // - 指定した一覧にはあるのに設定として保持してない -> キーアサインがない状態で追加 // - 指定した一覧に入ってないものが設定に含まれる -> 削除 - public void RefreshCustomActionKeys(GameInputActionKey[] actionKeys) + private void CheckCustomActionKeys() { + var actionKeys = _customActionKeys; + var currentKeys = KeyboardKeyAssign .CustomActions .Select(a => GameInputActionKey.Custom(a.CustomAction.CustomKey)) @@ -444,6 +459,9 @@ void ApplySetting(GameInputSetting setting) SendKeyboardKeyAssign(); GamepadKeyAssignUpdated?.Invoke(this, new(GamepadKeyAssign)); KeyboardKeyAssignUpdated?.Invoke(this, new(KeyboardKeyAssign)); + + //NOTE: ここも冗長になりうるが、冗長でもOK + CheckCustomActionKeys(); } void SendGamepadKeyAssign() diff --git a/WPF/VMagicMirrorConfig/ViewModel/MainWindowViewModel.cs b/WPF/VMagicMirrorConfig/ViewModel/MainWindowViewModel.cs index 5c64d6506..796a8f2be 100644 --- a/WPF/VMagicMirrorConfig/ViewModel/MainWindowViewModel.cs +++ b/WPF/VMagicMirrorConfig/ViewModel/MainWindowViewModel.cs @@ -64,7 +64,7 @@ public async void Initialize() await ModelResolver.Instance.Resolve().InitializeCustomMotionClipNamesAsync(); _runtimeHelper.Start(); ModelResolver.Instance.Resolve().Initialize(); - ModelResolver.Instance.Resolve().LoadSettingFromDefaultFile(); + ModelResolver.Instance.Resolve().InitializeAsync(); if (_settingModel.AutoLoadLastLoadedVrm.Value && !string.IsNullOrEmpty(_settingModel.LastVrmLoadFilePath)) { From c342f5878d5dcaa061e58687b98cda3e2670a438 Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Wed, 20 Dec 2023 22:52:06 +0900 Subject: [PATCH 14/27] remove commented out code --- .../KeyAssign/GameInputKeyboardKeyAssignItemViewModel.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/GameInputKeyboardKeyAssignItemViewModel.cs b/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/GameInputKeyboardKeyAssignItemViewModel.cs index dadafa1a2..346c76be0 100644 --- a/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/GameInputKeyboardKeyAssignItemViewModel.cs +++ b/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/GameInputKeyboardKeyAssignItemViewModel.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Windows.Input; namespace Baku.VMagicMirrorConfig.ViewModel @@ -9,9 +8,6 @@ public class GameInputKeyAssignItemViewModel public GameInputKeyAssignItemViewModel(GameInputActionKey actionKey, string keyCode) { ActionKey = actionKey; - //_actionItem = GameInputButtonActionItemViewModel.AvailableItems.FirstOrDefault(item => item.Action == action) - // ?? new GameInputButtonActionItemViewModel(GameInputButtonAction.None, ""); - KeyDownCommand = new ActionCommand(OnKeyDown); ClearInputCommand = new ActionCommand(ClearInput); SetKey(keyCode); From 74d2bdae2f9094943c7791e1c8a4a5e21c8c513c Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Thu, 21 Dec 2023 00:13:14 +0900 Subject: [PATCH 15/27] Avoid to save getter-only prop in game input --- .../Model/Entity/GameInputSetting.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs b/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs index 3862c617b..7b6d203c8 100644 --- a/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs +++ b/WPF/VMagicMirrorConfig/Model/Entity/GameInputSetting.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Windows.Input; +using Newtonsoft.Json; namespace Baku.VMagicMirrorConfig { @@ -112,17 +113,27 @@ public class GameInputGamepadKeyAssign public GameInputCustomAction CustomButtonView { get; set; } = new(); public GameInputCustomAction CustomButtonMenu { get; set; } = new(); + [JsonIgnore] public GameInputActionKey ButtonAKey => new(ButtonA, CustomButtonA); + [JsonIgnore] public GameInputActionKey ButtonBKey => new(ButtonB, CustomButtonB); + [JsonIgnore] public GameInputActionKey ButtonXKey => new(ButtonX, CustomButtonX); + [JsonIgnore] public GameInputActionKey ButtonYKey => new(ButtonY, CustomButtonY); + [JsonIgnore] public GameInputActionKey ButtonLButtonKey => new(ButtonLButton, CustomButtonLButton); + [JsonIgnore] public GameInputActionKey ButtonLTriggerKey => new(ButtonLTrigger, CustomButtonLTrigger); + [JsonIgnore] public GameInputActionKey ButtonRButtonKey => new(ButtonRButton, CustomButtonRButton); + [JsonIgnore] public GameInputActionKey ButtonRTriggerKey => new(ButtonRTrigger, CustomButtonRTrigger); + [JsonIgnore] public GameInputActionKey ButtonViewKey => new(ButtonView, CustomButtonView); + [JsonIgnore] public GameInputActionKey ButtonMenuKey => new(ButtonMenu, CustomButtonMenu); @@ -144,8 +155,11 @@ public class GameInputKeyboardKeyAssign public GameInputCustomAction CustomLeftClick { get; set; } = new(); public GameInputCustomAction CustomRightClick { get; set; } = new(); public GameInputCustomAction CustomMiddleClick { get; set; } = new(); + [JsonIgnore] public GameInputActionKey LeftClickKey => new(LeftClick, CustomLeftClick); + [JsonIgnore] public GameInputActionKey RightClickKey => new(RightClick, CustomRightClick); + [JsonIgnore] public GameInputActionKey MiddleClickKey => new(MiddleClick, CustomMiddleClick); From 5e1ca33dd6bb94c69f94ae1279c7a4edd7aebffd Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Thu, 21 Dec 2023 00:13:41 +0900 Subject: [PATCH 16/27] fix to initialize custom motion list in model layer --- .../Model/InterProcess/Util/CustomMotionList.cs | 10 +++------- .../Model/SettingModel/GameInputSettingModel.cs | 7 ++++++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs b/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs index f1f95179a..1b90b06e1 100644 --- a/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs +++ b/WPF/VMagicMirrorConfig/Model/InterProcess/Util/CustomMotionList.cs @@ -23,12 +23,9 @@ public CustomMotionList(IMessageSender sender) private readonly ObservableCollection _vrmaCustomMotionClipNames = new(); public ReadOnlyObservableCollection VrmaCustomMotionClipNames { get; } - private readonly TaskCompletionSource _customMotionsInitialized = new(); + private readonly TaskCompletionSource _initializeTcs = new(); - public async Task WaitCustomMotionsCompletedAsync() - { - await _customMotionsInitialized.Task; - } + public async Task WaitCustomMotionsCompletedAsync() => await _initializeTcs.Task; private readonly object _isInitializedLock = new(); private bool _isInitialized = false; @@ -54,8 +51,7 @@ public async Task InitializeCustomMotionClipNamesAsync() } IsInitialized = true; - _customMotionsInitialized.SetResult(true); - + _initializeTcs.SetResult(true); } private async Task GetCustomMotionClipNamesAsync(bool vrmaOnly) diff --git a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs index edee68194..dad90d6aa 100644 --- a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs +++ b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs @@ -151,7 +151,12 @@ public void SaveSetting(string filePath) public async void InitializeAsync() { LoadSetting(SpecialFilePath.GameInputDefaultFilePath); + await _motionList.WaitCustomMotionsCompletedAsync(); + _customActionKeys = _motionList.VrmaCustomMotionClipNames + .Select(GameInputActionKey.Custom) + .ToArray(); + CheckCustomActionKeys(); } @@ -464,7 +469,7 @@ void ApplySetting(GameInputSetting setting) CheckCustomActionKeys(); } - void SendGamepadKeyAssign() + private void SendGamepadKeyAssign() { var serializer = new JsonSerializer(); var sb = new StringBuilder(); From c95fb9caaac8fcbac5285e1a66570559fbdb1bb2 Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Thu, 21 Dec 2023 00:13:55 +0900 Subject: [PATCH 17/27] chore: reduce guard statement nest --- .../ViewModel/KeyAssign/KeyAssignViewModel.cs | 79 ++++++++++--------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/KeyAssignViewModel.cs b/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/KeyAssignViewModel.cs index e330dc140..3f5725f00 100644 --- a/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/KeyAssignViewModel.cs +++ b/WPF/VMagicMirrorConfig/ViewModel/KeyAssign/KeyAssignViewModel.cs @@ -71,51 +71,52 @@ internal KeyAssignViewModel(GameInputSettingModel model) ButtonActions = Array.Empty(); - if (!IsInDesignMode) + if (IsInDesignMode) { - WeakEventManager.AddHandler( - _model, - nameof(_model.GamepadKeyAssignUpdated), - OnGamepadKeyAssignUpdated - ); + return; + } - WeakEventManager.AddHandler( - _model, - nameof(_model.KeyboardKeyAssignUpdated), - OnKeyboardKeyAssignUpdated - ); + WeakEventManager.AddHandler( + _model, + nameof(_model.GamepadKeyAssignUpdated), + OnGamepadKeyAssignUpdated + ); - ButtonActions = _model.LoadAvailableActionKeys(); + WeakEventManager.AddHandler( + _model, + nameof(_model.KeyboardKeyAssignUpdated), + OnKeyboardKeyAssignUpdated + ); + ButtonActions = _model.LoadAvailableActionKeys(); - var keyAssignViewModels = new List(); - keyAssignViewModels.AddRange( - new (GameInputButtonAction action, string keyCode)[] - { - (GameInputButtonAction.Jump,_model.KeyboardKeyAssign.JumpKeyCode), - (GameInputButtonAction.Crouch, _model.KeyboardKeyAssign.CrouchKeyCode), - (GameInputButtonAction.Run, _model.KeyboardKeyAssign.RunKeyCode), - (GameInputButtonAction.Trigger, _model.KeyboardKeyAssign.TriggerKeyCode), - (GameInputButtonAction.Punch, _model.KeyboardKeyAssign.PunchKeyCode), - }.Select(pair => CreateKeyAssignItemViewModel( - GameInputActionKey.BuiltIn(pair.action), - pair.keyCode - ) - )); - - keyAssignViewModels.AddRange(_model - .LoadCustomActionKeys() - .Select(actionKey => CreateKeyAssignItemViewModel( - actionKey, - _model.FindKeyCodeOfCustomAction(actionKey) - ) - )); - - - foreach (var keyAssign in keyAssignViewModels) + var keyAssignViewModels = new List(); + keyAssignViewModels.AddRange( + new (GameInputButtonAction action, string keyCode)[] { - KeyAssigns.Add(keyAssign); - } + (GameInputButtonAction.Jump,_model.KeyboardKeyAssign.JumpKeyCode), + (GameInputButtonAction.Crouch, _model.KeyboardKeyAssign.CrouchKeyCode), + (GameInputButtonAction.Run, _model.KeyboardKeyAssign.RunKeyCode), + (GameInputButtonAction.Trigger, _model.KeyboardKeyAssign.TriggerKeyCode), + (GameInputButtonAction.Punch, _model.KeyboardKeyAssign.PunchKeyCode), + }.Select(pair => CreateKeyAssignItemViewModel( + GameInputActionKey.BuiltIn(pair.action), + pair.keyCode + ) + )); + + keyAssignViewModels.AddRange(_model + .LoadCustomActionKeys() + .Select(actionKey => CreateKeyAssignItemViewModel( + actionKey, + _model.FindKeyCodeOfCustomAction(actionKey) + ) + )); + + + foreach (var keyAssign in keyAssignViewModels) + { + KeyAssigns.Add(keyAssign); } } From bea295a44a340aed586527aaf94e31f5f987efd3 Mon Sep 17 00:00:00 2001 From: Baku Dreameater Date: Thu, 21 Dec 2023 00:35:31 +0900 Subject: [PATCH 18/27] Fix to bind correct property path in button based game action item --- .../SettingModel/GameInputSettingModel.cs | 9 ++--- .../View/GameInput/KeyAssignPanel.xaml | 3 +- .../ViewModel/KeyAssign/KeyAssignViewModel.cs | 36 +------------------ 3 files changed, 4 insertions(+), 44 deletions(-) diff --git a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs index dad90d6aa..fb2bbc89d 100644 --- a/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs +++ b/WPF/VMagicMirrorConfig/Model/SettingModel/GameInputSettingModel.cs @@ -406,7 +406,7 @@ public GameInputActionKey[] LoadCustomActionKeys() //NOTE: // 起動直後でcustomMotionListが空の状態で呼ぶと .vrma を含まない結果が戻ってしまうが、 // この問題は特にケアしない(ゲーム入力の設定ウィンドウが開くまでは呼ばれないはずなので) - public GameInputActionKey[] LoadAvailableActionKeys() + public GameInputActionKey[] GetAvailableActionKeys() { var result = new List() @@ -419,12 +419,7 @@ public GameInputActionKey[] LoadAvailableActionKeys() GameInputActionKey.BuiltIn(GameInputButtonAction.Punch), }; - foreach (var vrmaMotionKey in _motionList.VrmaCustomMotionClipNames) - { - - result.Add(GameInputActionKey.Custom(vrmaMotionKey)); - } - + result.AddRange(_customActionKeys); return result.ToArray(); } diff --git a/WPF/VMagicMirrorConfig/View/GameInput/KeyAssignPanel.xaml b/WPF/VMagicMirrorConfig/View/GameInput/KeyAssignPanel.xaml index bcda95c71..40644b375 100644 --- a/WPF/VMagicMirrorConfig/View/GameInput/KeyAssignPanel.xaml +++ b/WPF/VMagicMirrorConfig/View/GameInput/KeyAssignPanel.xaml @@ -28,7 +28,6 @@