输入系统编辑器重构

This commit is contained in:
梦语 2024-10-28 03:42:42 +08:00
parent f909e51ef3
commit f5c4c40236
36 changed files with 504 additions and 296 deletions

View File

@ -1,3 +1,4 @@
using UnityEngine;
namespace Ether namespace Ether
{ {

View File

@ -10,7 +10,7 @@ namespace Ether
/// <summary> /// <summary>
/// 生成类 /// 生成类
/// </summary> /// </summary>
public static void GenerateClass(string className, string baseClassName, string content, string generatePath) public static void GenerateClassFile(string className, string baseClassName, string content, string generatePath)
{ {
string tempClassStr = FileTools.ReadFile(PathTools.TempClassPath); string tempClassStr = FileTools.ReadFile(PathTools.TempClassPath);
tempClassStr = tempClassStr.Replace("$ClassName$", className); tempClassStr = tempClassStr.Replace("$ClassName$", className);
@ -19,5 +19,29 @@ namespace Ether
FileTools.WriteFile(generatePath, tempClassStr); FileTools.WriteFile(generatePath, tempClassStr);
} }
public static void GenerateEnumFile(string enumName, Dictionary<string, string> enumDic, string generatePath)
{
string tempEnumStr = FileTools.ReadFile(PathTools.TempEnumPath);
tempEnumStr = tempEnumStr.Replace("$EnumName$", enumName);
string tempStr = "";
foreach (var enumPair in enumDic)
{
if (!string.IsNullOrEmpty(enumPair.Value))
{
tempStr += $"\t\t[InspectorName(\"{enumPair.Value}\")]\n";
}
if (!string.IsNullOrEmpty(enumPair.Key))
{
tempStr += $"\t\t{enumPair.Key},\n";
}
}
tempEnumStr = tempEnumStr.Replace("$Content$", tempStr);
FileTools.WriteFile(generatePath, tempEnumStr);
}
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,26 @@
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Ether
{
public class EtherInputEditorWindow : OdinWindowBase<EtherInputEditorWindow>
{
[MenuItem("配置/输入系统 &i")]
private static void OpenWindow()
{
var window = GetWindow<EtherInputEditorWindow>();
window.titleContent = new GUIContent("输入系统");
}
protected override void OnInit()
{
DrawSearchToolbar = true;
AddSubWindow<EtherInputKeyEditorWindow>("按键配置");
AddSubWindow<EtherInputEventEditorWindow>("事件配置");
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9042b72ad83509647bfcde195f516cd0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,57 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEditor;
using UnityEngine;
namespace Ether
{
public class EtherInputEventEditorWindow : OdinSubWindowBase
{
[LabelText("事件列表"), TableList(ShowIndexLabels = true, AlwaysExpanded = true)]
public List<EtherInputEventEditorItem> eventList = new List<EtherInputEventEditorItem>();
public override void OnShow()
{
eventList.Clear();
string[] allName = CommonTools.GetAllEnumName<EtherInputEvent>();
InspectorNameAttribute[] allAttributeValue = CommonTools.GetEnumFieldAllAttribute<EtherInputEvent, InspectorNameAttribute>();
for (int i = 0; i < allName.Length; i++)
{
string desc = allAttributeValue[i] == null ? "" : allAttributeValue[i].displayName;
eventList.Add(new EtherInputEventEditorItem()
{
name = allName[i],
desc = desc
});
}
}
protected override void OnSave()
{
Dictionary<string, string> eventDic = new Dictionary<string, string>();
foreach (var eventItem in eventList)
{
eventDic.TryAdd(eventItem.name, eventItem.desc);
}
TempTools.GenerateEnumFile("EtherInputEvent", eventDic, PathTools.EtherInputEventPath);
AssetDatabase.Refresh();
}
[Serializable]
public class EtherInputEventEditorItem
{
[VerticalGroup("事件名"), HideLabel]
public string name;
[VerticalGroup("事件描述"), HideLabel]
public string desc;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9d21b0f6fd9c9e3438c8ef157fd7f861
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,39 @@
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
namespace Ether
{
public class EtherInputKeyEditorWindow : OdinSubWindowBase
{
[BoxGroup(Order = -1), HideLabel, EnumToggleButtons]
public DeviceType deviceType;
[LabelText("键盘按键列表"), ShowIf("deviceType", DeviceType.Keyboard), TableList(ShowIndexLabels = true, AlwaysExpanded = true)]
public List<EtherInputKeyCfg> keyboardCfgList = new List<EtherInputKeyCfg>();
[LabelText("手柄按键列表"), ShowIf("deviceType", DeviceType.Joystick), TableList(ShowIndexLabels = true, AlwaysExpanded = true)]
public List<EtherInputKeyCfg> joystickCfgList = new List<EtherInputKeyCfg>();
public override void OnShow()
{
keyboardCfgList.Clear();
joystickCfgList.Clear();
if (FileTools.ReadFileForJson(PathTools.EtherInputCfgDefaultPath, out Dictionary<DeviceType, List<EtherInputKeyCfg>> keyListDic))
{
keyListDic.TryGetValue(DeviceType.Keyboard, out keyboardCfgList);
keyListDic.TryGetValue(DeviceType.Joystick, out joystickCfgList);
}
}
protected override void OnSave()
{
Dictionary<DeviceType, List<EtherInputKeyCfg>> keyListDic = new();
keyListDic.Add(DeviceType.Keyboard, keyboardCfgList);
keyListDic.Add(DeviceType.Joystick, joystickCfgList);
FileTools.WriteFileForJson(PathTools.EtherInputCfgDefaultPath, keyListDic, isFormat: true);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9cd6d9bd67f54d34b8688ad6ae85d957
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -15,7 +15,7 @@ namespace Ether
{ {
public class ReInputEditorWindow : OdinMenuEditorWindow public class ReInputEditorWindow : OdinMenuEditorWindow
{ {
[MenuItem("配置/输入系统")] [MenuItem("配置/老版输入系统")]
private static void OpenWindow() private static void OpenWindow()
{ {
var window = GetWindow<ReInputEditorWindow>(); var window = GetWindow<ReInputEditorWindow>();
@ -265,7 +265,7 @@ namespace Ether
string saveContent = eventStr.Replace("%content%", tempStr); string saveContent = eventStr.Replace("%content%", tempStr);
FileTools.WriteFile(PathTools.ReInputEventCfgPath, saveContent); //FileTools.WriteFile(PathTools.ReInputEventCfgPath, saveContent);
} }
@ -328,7 +328,7 @@ namespace Ether
KeyboardDeviceList = new List<ReKey>(); KeyboardDeviceList = new List<ReKey>();
JoystickDeviceList = new List<ReKey>(); JoystickDeviceList = new List<ReKey>();
if (FileTools.ReadFileForJson(PathTools.ReInputCfgPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic)) if (FileTools.ReadFileForJson(PathTools.EtherInputCfgDefaultPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic))
{ {
if (rekeyListDic.ContainsKey(ReDeviceType.Keyboard)) if (rekeyListDic.ContainsKey(ReDeviceType.Keyboard))
{ {
@ -384,7 +384,7 @@ namespace Ether
window.ShowNotification(new GUIContent("已重置当前设置!")); window.ShowNotification(new GUIContent("已重置当前设置!"));
if (FileTools.ReadFileForJson(PathTools.ReInputCfgPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic)) if (FileTools.ReadFileForJson(PathTools.EtherInputCfgDefaultPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic))
{ {
switch (ReDeviceType) switch (ReDeviceType)
{ {
@ -476,7 +476,7 @@ namespace Ether
break; break;
} }
if (FileTools.ReadFileForJson(PathTools.ReInputCfgPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic)) if (FileTools.ReadFileForJson(PathTools.EtherInputCfgDefaultPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic))
{ {
switch (deviceType) switch (deviceType)
{ {
@ -551,7 +551,7 @@ namespace Ether
break; break;
} }
if (FileTools.ReadFileForJson(PathTools.ReInputCfgPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic)) if (FileTools.ReadFileForJson(PathTools.EtherInputCfgDefaultPath, out Dictionary<ReDeviceType, List<ReKey>> rekeyListDic))
{ {
switch (deviceType) switch (deviceType)
{ {
@ -576,7 +576,7 @@ namespace Ether
saveDeviceCfgDic.Add(ReDeviceType.Joystick, joystickKeyList); saveDeviceCfgDic.Add(ReDeviceType.Joystick, joystickKeyList);
FileTools.WriteFileForJson(PathTools.ReInputCfgPath, saveDeviceCfgDic, false, true); FileTools.WriteFileForJson(PathTools.EtherInputCfgDefaultPath, saveDeviceCfgDic, false, true);
} }
} }

View File

@ -0,0 +1,27 @@
using UnityEngine;
namespace Ether
{
public enum EtherInputEvent
{
[InspectorName("上")]
Up,
[InspectorName("下")]
Down,
[InspectorName("左")]
Left,
[InspectorName("右")]
Right,
[InspectorName("菜单")]
Menu,
[InspectorName("退出")]
Esc,
[InspectorName("交互1")]
Interaction1,
[InspectorName("交互2")]
Interaction2,
[InspectorName("交互3")]
Interaction3,
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b50603c11c1736e44b27c994283801fd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,44 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
namespace Ether
{
[Serializable]
public class EtherInputKeyCfg
{
[VerticalGroup("键"), HideLabel]
public KeyCode KeyCode;
[VerticalGroup("键类型"), HideLabel]
public EtherInputKeyType KeyType;
[VerticalGroup("键描述"), HideLabel]
public string KeyDescription;
[VerticalGroup("绑定事件")]
[LabelText("事件列表")]
public List<EtherInputEvent> EventList = new List<EtherInputEvent>();
[VerticalGroup("排序"), HideLabel, ShowIf("KeyType", EtherInputKeyType.Interaction)]
public int SortIndex;
}
[Serializable]
public enum EtherInputKeyType
{
[InspectorName("动作")]
Action = 0,
[InspectorName("交互")]
Interaction = 1,
}
public enum DeviceType
{
[InspectorName("键盘")]
Keyboard = 0,
[InspectorName("手柄")]
Joystick = 1,
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7ce5123c3cae8742bba4a0d801c4cad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,11 +1,11 @@
using System.ComponentModel; using UnityEngine;
namespace Ether namespace Ether
{ {
public enum ReInputEvent public enum ReInputEvent
{ {
[Description("移动")] [InspectorName("移动")]
Move, Move,
} }
} }

View File

@ -7,12 +7,6 @@ using UnityEngine.InputSystem;
namespace Ether namespace Ether
{ {
public enum DeviceType
{
Keyboard,
Gamepad,
}
public class ReInputManager : SingletonAutoMono<ReInputManager> public class ReInputManager : SingletonAutoMono<ReInputManager>
{ {
ReInputActions inputActions; ReInputActions inputActions;

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 727ef86d82981b645809f394db91d417 guid: 9004ae0a1e4c14e4aadb9e0d30ba3fc3
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -22,7 +22,7 @@ namespace Ether
{ {
public class FrameCodeGenerate public class FrameCodeGenerate
{ {
private static string templeteBaseFileName = Application.dataPath + $"/Ether/Editor/Frames/FrameBaseTemplete.txt"; private static string templeteBaseFileName = Application.dataPath + $"/Ether/Scripts/Module/UI/Editor/FrameBaseTemplete.txt";
public static string GenerateFrameBaseCode(string prefabPath, string baseDirectoryPath, Dictionary<string, string> componentTypeDic) public static string GenerateFrameBaseCode(string prefabPath, string baseDirectoryPath, Dictionary<string, string> componentTypeDic)
{ {
@ -168,147 +168,5 @@ namespace Ether
return code; return code;
} }
//=================================== 以下是老代码 =========================================
//public enum ComponentType
//{
// Image,
// Go,
// Btn,
// BtnEx,
// Text,
// SRContent,
// ScrollRect,
// Animator,
// Trans,
//}
//private static Dictionary<ComponentType, string> relationDic = new Dictionary<ComponentType, string>()
//{
// { ComponentType.Image, "Image" },
// { ComponentType.Go, "GameObject" },
// { ComponentType.Trans, "Transform" },
// { ComponentType.Btn, "Button" },
// { ComponentType.BtnEx, "ButtonEx" },
// { ComponentType.Text, "TextMeshProUGUI" },
// { ComponentType.SRContent, "ScrollContent" },
// { ComponentType.ScrollRect, "ScrollRect" },
// { ComponentType.Animator, "Animator" },
//};
//private static string templeteFileName = Application.dataPath + $"/Ether/Editor/Frames/FrameBaseTemplete.txt";
///// <summary>
///// 生成FrameBase
///// </summary>
///// <param name="componentDic"></param>
//private static void GenerateFrameBase(GameObject selectedPrefab, Dictionary<string, (string, List<ComponentType>)> componentDic)
//{
// string selectPath = AssetDatabase.GetAssetPath(selectedPrefab);
// string framePart = "Prefabs";
// int selectIndex = selectPath.IndexOf(framePart);
// string framePrefabPath = selectPath.Substring(selectIndex).Replace(".prefab", "");
// Debug.Log($"selectPath:{selectPath}");
// string frameTemplete = FileTools.ReadFile(templeteFileName);
// Debug.Log(frameTemplete);
// (string, string) generateComponentCode = GenerateComponentCodeStr(componentDic);
// string pattern = @"\$(.*?)\$";
// MatchCollection matches = Regex.Matches(frameTemplete, pattern);
// foreach (Match match in matches)
// {
// string property = match.Groups[0].Value; //带$的原字符串
// string content = match.Groups[1].Value; //仅两个$中的内容
// string replaceStr = "";
// switch (content)
// {
// case "FrameBaseName":
// replaceStr = $"{selectedPrefab.name}Base";
// break;
// case "PrefabPath":
// replaceStr = framePrefabPath;
// break;
// case "PropertyList":
// replaceStr = generateComponentCode.Item1;
// break;
// case "PropertyInitList":
// replaceStr = generateComponentCode.Item2;
// break;
// default:
// break;
// }
// //Debug.Log(content);
// frameTemplete = frameTemplete.Replace(property, replaceStr);
// }
// string basePath = Application.dataPath + $"/Scripts/AutoGenerated/FrameBase/{selectedPrefab.name}Base.cs";
// if (File.Exists(basePath)) File.Delete(basePath);
// FileTools.WriteFile(basePath, frameTemplete);
// AssetDatabase.Refresh();
// return;
//}
//private static (string, string) GenerateComponentCodeStr(Dictionary<string, (string, List<ComponentType>)> componentDic)
//{
// string define = "";
// string code = "";
// string name = "";
// foreach (var component in componentDic)
// {
// name = component.Value.Item1;
// foreach (var type in component.Value.Item2)
// {
// string tempType;
// if (relationDic.ContainsKey(type))
// {
// tempType = relationDic[type];
// }
// else
// {
// tempType = type.ToString();
// }
// define += $"protected {tempType} _{type}{name};\n\t\t";
// code += GetCodeByComponentType(type, tempType, name, component.Key);
// }
// }
// return (define, code);
//}
//private static string GetCodeByComponentType(ComponentType type, string componentName, string name, string path)
//{
// string code = "";
// switch (type)
// {
// case ComponentType.Go:
// code = $"_{type}{name} = GetChild(\"{path}\").gameObject;\n\t\t\t";
// break;
// case ComponentType.Image:
// case ComponentType.Btn:
// case ComponentType.BtnEx:
// case ComponentType.Text:
// default:
// code = $"_{type}{name} = GetComponent<{componentName}>(\"{path}\");\n\t\t\t";
// break;
// }
// return code;
//}
} }
} }

View File

@ -0,0 +1,3 @@
{
"reference": "GUID:2f716c3cfa97f8d4bb5abb0809a10755"
}

View File

@ -1,7 +1,6 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 3949494a94dc80b44a7cf3ce7f78f4cf guid: 16e101f9b4f56e046a139bb2305927b2
folderAsset: yes AssemblyDefinitionReferenceImporter:
DefaultImporter:
externalObjects: {} externalObjects: {}
userData: userData:
assetBundleName: assetBundleName:

View File

@ -16,11 +16,11 @@ namespace Ether
public class FrameEditorWindow : OdinEditorWindow public class FrameEditorWindow : OdinEditorWindow
{ {
private static string templeteFramePrefabPath = Application.dataPath + $"/Ether/Editor/Frames/TempFrame.prefab"; //预制体模板路径 private static string templeteFramePrefabPath = Application.dataPath + $"/Ether/Scripts/Module/UI/Editor/TempFrame.prefab"; //预制体模板路径
static FrameEditorWindow window; static FrameEditorWindow window;
[MenuItem("工具/界面/UI界面设置 %/")] [MenuItem("配置/界面/UI界面设置 &f")]
//[Shortcut("打开全局配置", KeyCode.F1)] //[Shortcut("打开全局配置", KeyCode.F1)]
private static void OpenWindow() private static void OpenWindow()
{ {
@ -137,7 +137,7 @@ namespace Ether
{ {
Directory.CreateDirectory(directoryPath); Directory.CreateDirectory(directoryPath);
} }
TempTools.GenerateClass(createFrameName, $"{createFrameName}Base", "", framePath); TempTools.GenerateClassFile(createFrameName, $"{createFrameName}Base", "", framePath);
} }

View File

@ -15,16 +15,16 @@ namespace Ether
public static string ReInputCfgPersistentPath = Application.persistentDataPath + "/Config/Input/ReInputConfig.json"; public static string ReInputCfgPersistentPath = Application.persistentDataPath + "/Config/Input/ReInputConfig.json";
public static string ReInputCfgPath = Application.streamingAssetsPath + "/Config/Input/ReInputConfig.json";
public static string ReInputEventCfgPath = Application.dataPath + "/Ether/Scripts/Module/Input/ReInput/ReInputEvent.cs";
public static string EtherInputCfgDefaultPath = Application.streamingAssetsPath + "/Config/Input/ReInputConfig.json";
public static string EtherInputEventPath = Application.dataPath + "/Ether/Scripts/Module/Input/EtherInputEvent.cs";
public static string SceneAudioCfg = Application.streamingAssetsPath + "/Config/Audio/SceneAudioCfg.json"; public static string SceneAudioCfg = Application.streamingAssetsPath + "/Config/Audio/SceneAudioCfg.json";
public static string TempEnumPath = Application.dataPath + "/Ether/Editor/Templete/TempEnum.txt"; public static string TempEnumPath = Application.dataPath + "/Ether/Editor/Templete/TempEnum.txt";
public static string TempClassPath = Application.dataPath + "/Ether/Editor/Templete/TempClass.txt"; public static string TempClassPath = Application.dataPath + "/Ether/Editor/Templete/TempClass.txt";
public static string FrameEditorCfgPath = Application.dataPath + $"/Ether/Editor/Frames/FrameEditorCfg.json"; public static string FrameEditorCfgPath = Application.dataPath + $"/Ether/Scripts/Module/UI/Editor/FrameEditorCfg.json";

View File

@ -18,8 +18,8 @@ namespace Ether
{ {
public class GlobalWindow : OdinMenuEditorWindow public class GlobalWindow : OdinMenuEditorWindow
{ {
[MenuItem("配置/全局配置")] [MenuItem("配置/全局配置 &1")]
[Shortcut("打开全局配置", KeyCode.F1)] //[Shortcut("打开全局配置", KeyCode.F1)]
private static void OpenWindow() private static void OpenWindow()
{ {
var window = GetWindow<GlobalWindow>(); var window = GetWindow<GlobalWindow>();

View File

@ -8,7 +8,7 @@ namespace Ether
{ {
public class TableEditorWindow : OdinWindowBase<TableEditorWindow> public class TableEditorWindow : OdinWindowBase<TableEditorWindow>
{ {
[MenuItem("配置/表格配置 %t")] [MenuItem("配置/表格配置 &t")]
private static void OpenWindow() private static void OpenWindow()
{ {
var window = GetWindow<TableEditorWindow>(); var window = GetWindow<TableEditorWindow>();

View File

@ -4,50 +4,74 @@
"KeyCode": 119, "KeyCode": 119,
"KeyType": 0, "KeyType": 0,
"KeyDescription": "上", "KeyDescription": "上",
"Event": 0, "EventList": [
0
],
"SortIndex": 0 "SortIndex": 0
}, },
{ {
"KeyCode": 115, "KeyCode": 115,
"KeyType": 0, "KeyType": 0,
"KeyDescription": "下", "KeyDescription": "下",
"Event": 1, "EventList": [
1
],
"SortIndex": 0 "SortIndex": 0
}, },
{ {
"KeyCode": 97, "KeyCode": 97,
"KeyType": 0, "KeyType": 0,
"KeyDescription": "左", "KeyDescription": "左",
"Event": 2, "EventList": [
2
],
"SortIndex": 0 "SortIndex": 0
}, },
{ {
"KeyCode": 100, "KeyCode": 100,
"KeyType": 0, "KeyType": 0,
"KeyDescription": "右", "KeyDescription": "右",
"Event": 3, "EventList": [
3
],
"SortIndex": 0 "SortIndex": 0
}, },
{ {
"KeyCode": 102, "KeyCode": 102,
"KeyType": 1, "KeyType": 1,
"KeyDescription": "交互按键1", "KeyDescription": "交互按键1",
"Event": 0, "EventList": [
6
],
"SortIndex": 0 "SortIndex": 0
}, },
{ {
"KeyCode": 103, "KeyCode": 103,
"KeyType": 1, "KeyType": 1,
"KeyDescription": "交互按键2", "KeyDescription": "交互按键2",
"Event": 0, "EventList": [
7
],
"SortIndex": 1 "SortIndex": 1
}, },
{ {
"KeyCode": 104, "KeyCode": 104,
"KeyType": 1, "KeyType": 1,
"KeyDescription": "交互按键3", "KeyDescription": "交互按键3",
"Event": 0, "EventList": [
8
],
"SortIndex": 2 "SortIndex": 2
},
{
"KeyCode": 27,
"KeyType": 0,
"KeyDescription": "菜单/退出",
"EventList": [
4,
5
],
"SortIndex": 0
} }
], ],
"Joystick": [ "Joystick": [
@ -55,7 +79,7 @@
"KeyCode": 0, "KeyCode": 0,
"KeyType": 0, "KeyType": 0,
"KeyDescription": null, "KeyDescription": null,
"Event": 0, "EventList": [],
"SortIndex": 0 "SortIndex": 0
} }
] ]