Unity中能否获取InputManager映射的前后左右按键?
嘿,这个问题我之前也踩过坑!Unity的InputManager确实没有直接暴露Runtime可用的API来获取按键映射,但有几种实用的方法能解决你的需求,分情况给你说明:
一、优先推荐:直接用Input Manager的自定义轴/按钮名称检测(不用关心具体按键)
这其实是Unity设计InputManager的初衷——不管用户怎么改按键绑定,你只需要用配置好的轴名称或按钮名称来检测输入,Unity内部会自动处理映射关系。
比如你在InputManager里把“向上”指令设为名为MoveUp的轴(绑定W、上箭头,后来用户改成U),直接在脚本里这么写:
void Update() { // 检测按键按下 if (Input.GetButtonDown("MoveUp")) { Debug.Log("向上指令触发(不管用户绑了啥键)"); // 这里加你的按下逻辑 } // 检测按键释放 if (Input.GetButtonUp("MoveUp")) { Debug.Log("向上指令结束"); // 这里加你的释放逻辑 } }
这种方法完全不用管用户改了什么按键,省心又稳定,90%的场景都用这个就够了。
二、如果确实需要获取绑定的KeyCode(比如显示给玩家当前按键)
如果你的需求是要知道用户具体绑了哪个键(比如在设置界面显示“向上:U”),那得用以下两种方式:
1. 编辑器环境下读取InputManager配置
写个Editor脚本,用SerializedObject访问InputManager的配置文件,这个只能在Unity编辑器里用(比如做编辑器工具或设置界面):
using UnityEditor; using UnityEngine; public class InputMappingViewer : EditorWindow { [MenuItem("Tools/查看输入映射")] public static void OpenViewer() { GetWindow<InputMappingViewer>("当前输入映射"); } void OnGUI() { // 加载InputManager配置文件 var inputManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]); var axes = inputManager.FindProperty("m_Axes"); // 遍历所有轴 for (int i = 0; i < axes.arraySize; i++) { var axis = axes.GetArrayElementAtIndex(i); string axisName = axis.FindPropertyRelative("m_Name").stringValue; string positiveBtn = axis.FindPropertyRelative("m_PositiveButton").stringValue; string negativeBtn = axis.FindPropertyRelative("m_NegativeButton").stringValue; GUILayout.Label($"轴名称: {axisName}"); GUILayout.Label($"正向按键: {positiveBtn}"); GUILayout.Label($"负向按键: {negativeBtn}"); GUILayout.Space(15); } inputManager.ApplyModifiedProperties(); } }
2. Runtime下获取映射(需要提前导出配置)
Runtime下Unity不会把InputManager.asset打包进游戏,所以得先在编辑器里把映射导出成自定义配置文件(比如JSON),再在游戏里读取:
第一步:写Editor脚本导出映射为JSON
using UnityEditor; using UnityEngine; using System.IO; using System.Collections.Generic; public class InputMappingExporter : EditorWindow { [MenuItem("Tools/导出输入映射")] public static void ExportMappings() { var inputManager = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]); var axes = inputManager.FindProperty("m_Axes"); var axisList = new List<InputAxisData>(); for (int i = 0; i < axes.arraySize; i++) { var axis = axes.GetArrayElementAtIndex(i); var data = new InputAxisData { name = axis.FindPropertyRelative("m_Name").stringValue, positiveButton = axis.FindPropertyRelative("m_PositiveButton").stringValue, negativeButton = axis.FindPropertyRelative("m_NegativeButton").stringValue }; axisList.Add(data); } // 导出到Assets目录下的JSON文件 string json = JsonUtility.ToJson(new InputAxisCollection { axes = axisList }, true); string savePath = Path.Combine(Application.dataPath, "InputMappings.json"); File.WriteAllText(savePath, json); AssetDatabase.Refresh(); Debug.Log($"输入映射已导出到: {savePath}"); } [System.Serializable] private class InputAxisCollection { public List<InputAxisData> axes; } [System.Serializable] private class InputAxisData { public string name; public string positiveButton; public string negativeButton; } }
第二步:Runtime读取JSON并检测按键
using UnityEngine; using System.Collections.Generic; public class InputMappingReader : MonoBehaviour { private Dictionary<string, KeyCode> positiveKeyMap = new Dictionary<string, KeyCode>(); void Start() { // 读取JSON文件 TextAsset jsonFile = Resources.Load<TextAsset>("InputMappings"); var axisCollection = JsonUtility.FromJson<InputAxisCollection>(jsonFile.text); // 把按键字符串转成KeyCode存入字典 foreach (var axisData in axisCollection.axes) { if (!string.IsNullOrEmpty(axisData.positiveButton)) { KeyCode key = (KeyCode)System.Enum.Parse(typeof(KeyCode), axisData.positiveButton); positiveKeyMap[axisData.name] = key; } } } void Update() { // 检测"MoveUp"对应的按键按下 if (positiveKeyMap.TryGetValue("MoveUp", out KeyCode upKey)) { if (Input.GetKeyDown(upKey)) { Debug.Log($"检测到{upKey}按下,对应MoveUp指令"); } } } [System.Serializable] private class InputAxisCollection { public List<InputAxisData> axes; } [System.Serializable] private class InputAxisData { public string name; public string positiveButton; public string negativeButton; } }
总结
- 只是处理按键的按下/释放逻辑:优先用
Input.GetButtonDown/Input.GetButtonUp配合InputManager的轴名称,这是最稳妥的方案。 - 需要获取具体绑定的KeyCode:用Editor脚本读取或导出配置,再在Runtime里使用。
内容的提问来源于stack exchange,提问作者Penjimon
相关产品推荐
相关产品推荐

