You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为Unity角色控制器自定义横竖轴是否具备可行性?

复刻Unity默认Horizontal/Vertical轴并支持运行时按键重绑定

看起来你已经找对了方向——Unity默认的Input Manager轴确实不支持运行时修改绑定,所以自己实现一套自定义轴系统是最佳方案。下面我会基于你的思路,完善代码并补充关键功能,让它完全复刻默认轴的行为同时支持动态按键重绑定。

完整实现代码

using UnityEngine;
using System;

public class CustomInputAxis : MonoBehaviour
{
    // 可序列化的按键绑定类,支持Inspector编辑和运行时修改
    [Serializable]
    public class AxisBinding
    {
        public KeyCode positiveKey = KeyCode.D;
        public KeyCode negativeKey = KeyCode.A;
        public float sensitivity = 1f;
        public float gravity = 3f;
        public float deadZone = 0.001f;
        public float snap = 0f;
    }

    [Header("水平轴设置")]
    public AxisBinding horizontalAxis = new AxisBinding();
    [Header("垂直轴设置")]
    public AxisBinding verticalAxis = new AxisBinding();

    // 对应Unity Input.GetAxis的平滑输出值
    public float Horizontal { get; private set; }
    public float Vertical { get; private set; }
    // 对应Unity Input.GetAxisRaw的原始输出值(无平滑)
    public float HorizontalRaw { get; private set; }
    public float VerticalRaw { get; private set; }

    private void Update()
    {
        UpdateAxis(ref Horizontal, ref HorizontalRaw, horizontalAxis);
        UpdateAxis(ref Vertical, ref VerticalRaw, verticalAxis);
    }

    // 核心逻辑:完全复刻Unity默认轴的输入处理流程
    private void UpdateAxis(ref float currentValue, ref float rawValue, AxisBinding binding)
    {
        // 读取原始按键输入
        rawValue = 0f;
        if (Input.GetKey(binding.positiveKey))
            rawValue += 1f;
        if (Input.GetKey(binding.negativeKey))
            rawValue -= 1f;

        // 应用死区过滤微小误触
        if (Mathf.Abs(rawValue) < binding.deadZone)
            rawValue = 0f;

        // Snap逻辑:松开按键时立即归0(类似Unity部分轴的行为)
        if (binding.snap > 0f && rawValue == 0f)
        {
            currentValue = 0f;
            return;
        }

        // 计算目标值并应用灵敏度
        float targetValue = rawValue * binding.sensitivity;

        // 应用重力实现平滑过渡(模拟Unity轴的缓动效果)
        currentValue = Mathf.MoveTowards(currentValue, targetValue, binding.gravity * Time.deltaTime);
    }

    // 运行时修改水平轴按键的方法
    public void SetHorizontalBinding(KeyCode positiveKey, KeyCode negativeKey)
    {
        horizontalAxis.positiveKey = positiveKey;
        horizontalAxis.negativeKey = negativeKey;
    }

    // 运行时修改垂直轴按键的方法
    public void SetVerticalBinding(KeyCode positiveKey, KeyCode negativeKey)
    {
        verticalAxis.positiveKey = positiveKey;
        verticalAxis.negativeKey = negativeKey;
    }

    // 快速获取移动向量的便捷方法
    public Vector2 GetMoveVector()
    {
        return new Vector2(Horizontal, Vertical);
    }
}

关键功能说明

  • 可自定义的绑定参数AxisBinding类复刻了Unity默认轴的所有核心参数(灵敏度、重力、死区等),既可以在Inspector里可视化编辑,也能在运行时动态修改。
  • 1:1复刻默认轴行为UpdateAxis方法完全模拟Unity Input.GetAxis的处理逻辑,包括平滑过渡、死区过滤、Snap归0等细节,保证你的移动手感和默认轴一致。
  • 运行时重绑定支持:通过SetHorizontalBindingSetVerticalBinding方法,你可以在任何场景(比如设置界面的按键绑定弹窗)调用这些方法,实时修改玩家的移动按键。

使用示例

在你的移动脚本里直接调用即可:

public class PlayerMovement : MonoBehaviour
{
    public float moveSpeed = 5f;
    private CustomInputAxis customInput;

    private void Awake()
    {
        customInput = GetComponent<CustomInputAxis>();
    }

    private void Update()
    {
        Vector2 moveDir = customInput.GetMoveVector();
        transform.Translate(moveDir * moveSpeed * Time.deltaTime, Space.World);
    }

    // 比如在设置界面调用这个方法修改按键
    public void RebindHorizontalKeys(KeyCode positive, KeyCode negative)
    {
        customInput.SetHorizontalBinding(positive, negative);
    }
}

扩展建议

  • 如果需要支持手柄输入,可以在AxisBinding中添加手柄轴字段,结合Input.GetAxis读取手柄摇杆输入;
  • 可以添加按键绑定的保存/加载功能,用PlayerPrefs存储用户自定义的按键配置;
  • 若要支持多输入设备切换,可以扩展成输入映射表,区分键盘、手柄、触摸屏等不同输入源。

内容的提问来源于stack exchange,提问作者Nehiso

火山引擎 最新活动