Unity C#:如何在游戏运行时通过脚本重绑定按键?
Unity运行时修改Input Manager按键绑定实现控制菜单
两种实现方案(分Editor/打包后场景)
方案一:Editor环境下直接修改Input Manager配置
如果仅在编辑器内测试或制作工具,可以通过SerializedObject直接修改InputManager.asset的配置,代码示例如下:
using UnityEditor; using UnityEngine; using System.Collections; public class KeyRebindEditorTool : MonoBehaviour { // 目标Input轴名称(需和Input Manager中设置的一致,比如"Jump") public string targetAxis = "Jump"; // 触发按键绑定流程 public void StartRebind() { Debug.Log("请按下要绑定的新按键..."); StartCoroutine(WaitForKeyInput()); } private IEnumerator WaitForKeyInput() { while (true) { // 遍历所有按键检测玩家输入 foreach (KeyCode key in System.Enum.GetValues(typeof(KeyCode))) { if (Input.GetKeyDown(key)) { UpdateAxisPositiveKey(targetAxis, key); yield break; } } yield return null; } } private void UpdateAxisPositiveKey(string axisName, KeyCode newKey) { // 加载InputManager配置文件 var inputManagerAsset = AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/InputManager.asset")[0]; var serializedObj = new SerializedObject(inputManagerAsset); var axesProp = serializedObj.FindProperty("m_Axes"); // 遍历找到目标轴并修改正输入键 for (int i = 0; i < axesProp.arraySize; i++) { var axisProp = axesProp.GetArrayElementAtIndex(i); if (axisProp.FindPropertyRelative("m_Name").stringValue == axisName) { axisProp.FindPropertyRelative("positiveButton").stringValue = newKey.ToString(); serializedObj.ApplyModifiedProperties(); AssetDatabase.SaveAssets(); Debug.Log($"已将{axisName}的正输入键改为{newKey}"); break; } } } }
方案二:打包后游戏的通用解决方案(推荐)
打包后的游戏无法修改InputManager.asset,因此建议自定义输入逻辑,结合PlayerPrefs存储按键映射,确保重启游戏后设置依然有效:
1. 自定义输入管理类
using UnityEngine; using System.Collections.Generic; public class CustomInputSystem : MonoBehaviour { // 默认按键配置,与Input Manager中的轴一一对应 private readonly Dictionary<string, KeyCode> _defaultKeys = new() { {"Jump", KeyCode.Space}, {"MoveForward", KeyCode.W}, {"MoveBackward", KeyCode.S} }; private Dictionary<string, KeyCode> _customKeys; void Awake() { _customKeys = new Dictionary<string, KeyCode>(); LoadSavedBindings(); } // 加载已保存的按键绑定 private void LoadSavedBindings() { foreach (var keyPair in _defaultKeys) { string saveKey = $"InputBind_{keyPair.Key}"; if (PlayerPrefs.HasKey(saveKey)) { _customKeys[keyPair.Key] = (KeyCode)PlayerPrefs.GetInt(saveKey); } else { _customKeys[keyPair.Key] = keyPair.Value; } } } // 对外提供按键按下检测方法 public bool GetKeyDown(string inputName) { return _customKeys.TryGetValue(inputName, out var key) && Input.GetKeyDown(key); } // 对外提供按键按住检测方法 public bool GetKey(string inputName) { return _customKeys.TryGetValue(inputName, out var key) && Input.GetKey(key); } // 保存新的按键绑定 public void SaveBinding(string inputName, KeyCode newKey) { if (_customKeys.ContainsKey(inputName)) { _customKeys[inputName] = newKey; PlayerPrefs.SetInt($"InputBind_{inputName}", (int)newKey); PlayerPrefs.Save(); } } // 恢复默认按键配置 public void RestoreDefaults() { foreach (var keyPair in _defaultKeys) { _customKeys[keyPair.Key] = keyPair.Value; PlayerPrefs.SetInt($"InputBind_{keyPair.Key}", (int)keyPair.Value); } PlayerPrefs.Save(); } }
2. 控制菜单绑定逻辑示例
在UI菜单脚本中添加如下逻辑,处理按键绑定交互:
using UnityEngine; public class ControlMenu : MonoBehaviour { public CustomInputSystem inputSystem; private bool _isRebinding; private string _currentRebindInput; // 点击"绑定跳跃键"按钮时调用 public void StartRebindJump() { StartRebindProcess("Jump"); } // 点击"绑定前进键"按钮时调用 public void StartRebindForward() { StartRebindProcess("MoveForward"); } private void StartRebindProcess(string inputName) { _currentRebindInput = inputName; _isRebinding = true; // 此处可更新UI提示,比如显示"请按下新的XX键" Debug.Log($"请按下新的{inputName}按键..."); } void Update() { if (!_isRebinding) return; foreach (KeyCode key in System.Enum.GetValues(typeof(KeyCode))) { if (Input.GetKeyDown(key)) { inputSystem.SaveBinding(_currentRebindInput, key); _isRebinding = false; // 更新UI显示绑定后的按键 Debug.Log($"{_currentRebindInput}已绑定到{key}"); break; } } } // 点击"恢复默认"按钮时调用 public void ResetToDefaults() { inputSystem.RestoreDefaults(); // 更新UI显示默认按键 Debug.Log("已恢复默认按键配置"); } }
关键说明
- 方案一仅适用于Unity Editor环境,打包后会因
AssetDatabase属于Editor命名空间报错 - 方案二更适合正式发布的游戏,兼容性和可靠性更高
- 以上代码针对旧版Input Manager,若使用Unity新Input System,实现逻辑会有所不同
内容的提问来源于stack exchange,提问作者TheWIzard
相关产品推荐
相关产品推荐

