【问题标题】:How to check for both WASD and arrow keys input simultaneously in unity?如何统一检查WASD和箭头键同时输入?
【发布时间】:2022-08-13 21:07:00
【问题描述】:

我正在开发一款与Subway Surfers 具有相似玩家机制的游戏,即当用户给出相应的输入时,玩家会切换车道。

private void Update() {
    if (Input.GetKeyDown(KeyCode.A)) {
        ChangeLane(-1);
    } else if (Input.GetKeyDown(KeyCode.D)) {
        ChangeLane(1);
    }
}

这个 sn-p 基本上检查用户输入并使用ChangeLane(int) 方法让用户切换车道,参数-1 表示玩家切换到左侧车道,1 表示玩家切换到右车道。


问题:

我想检查两者W一个小号D在我的脚本中同时输入键和箭头键。
想到这里,立刻想到的是:

if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow) { ... }

我想做一些检查两者的事情一个和左箭头只有一个 if 支票,而不是像上面所示的那样分开。


我试过的:

Input.GetAxis(\"Horizontal\"),但这在这种情况下不起作用,因为只要按下键,这个值就会增加直到 1

接下来,Input.GetAxisRaw(\"Horizontal\"),这几乎起作用了,只要按下键就会返回1

int horizontalInput = (int)Input.GetAxisRaw(\"Horizontal\");

if (horizontalInput != 0) {
    ChangeLane(horizontalInput);
}

我在输入管理器中的水平轴:

但....

Input.GetAxis(string)Input.GetAxisRaw(string) 的工作方式与 Input.GetKey(KeyCode) 类似,但我想要像 Input.GetKeyDown(KeyCode) 一样工作的东西。


PS:我希望得到一个不包括在按下按钮后使用boolean 标志跳过帧的答案。

    标签: c# unity3d


    【解决方案1】:

    Unity InputManager 允许您为轴上的正负按钮指定主键和备用键。

    您可以将“水平”轴配置为使用“w”表示正数,“s”表示负数,“向上箭头”表示 alt 正数,“向下箭头”表示 alt 负数。然后你应该使用 GetAxisRaw。

    使用 InputManager 允许您从代码中抽象出输入的配置。 InputManager 可以配置为使用控制器、赛车设置、键盘等,而无需对代码进行任何修改。虽然它的功能与GetKey 相同,但它允许您避免硬编码按钮按下。

    为什么要使用 GetAxisRaw 的旁注:GetAxis 平滑输入,这就是为什么它需要一些时间才能达到 1 或 -1。 GetAxisRaw 提供即时输入。

    看来您实际上并不想要 WASD/箭头连续控制您的角色,而是想要冲动控制。换句话说,您不希望更长的按钮按下来进一步影响角色的移动。相反,请考虑使用GetButtonDown 并在您的 InputManager 中适当地定义按钮。

    【讨论】:

    • 请注意,我在第三句话之后确实评论了为什么您应该使用输入管理器。我读了你的整个问题。 @GeekyQuentin
    • 我的问题清楚地提到了我对输入管理器的使用
    • 我已经更新了我的评论以在 InputManager 中识别 GetButtonDown,这可以满足您的需求。 @GeekyQuentin 这个网站是一个调试的地方。与其对未完全回答您问题的答案做出尖刻/好斗的回答,不如尝试有效地纠正误解。
    • GetButtonDown 有助于检测按钮按下的程度,但它无助于找出是否按下了 <kbd>A</kbd> 或 <kbd>W</kbd>
    • 您可以在输入管理器中定义按钮。文档中的示例是“Fire1”,但您可以创建和定义“JumpLeft”和“JumpRight”。然后您可以将这些键分配给这些按钮。
    【解决方案2】:

    我建议您使用与先前值相异的技术。

    private int perviousInput; //cache last input
    
    public void Update()
    {
        int horizontalInput = (int)Input.GetAxisRaw("Horizontal");
    
        if (horizontalInput == perviousInput) return;
        
        if (horizontalInput != 0) {
            Debug.Log(horizontalInput);
        }
    
        perviousInput = horizontalInput;
    }
    

    【讨论】:

    • 感谢这个方法,我想要的是......,当我说Input.GetAxisInput.GetKey 类似时,你明白了吗?相似之处在于,它们每帧都返回true,而Input.GetKeyDown 仅返回键被按下的帧true。我正在寻找类似于Input.GetKeyDown 的东西,即仅在按键的第一帧返回true
    • @GeekyQuentin 如果您的目标是避免不必要的处理,那么问题的解决方案是使用 Unity 的新输入系统,该系统通过在按下时调用事件来工作并且是最佳的。如果要使用旧系统,不知道有没有具体的解决办法。
    【解决方案3】:

    这通常是通过加法组合输入来完成的,允许考虑竞争输入并在它们平衡时取消。例如,如果您同时持有 A 和 D,则什么也不做。如果同时按 A 和 LeftArrow,则此帧的输入为 Left。意识到您必须准确地确定每帧的输入是什么,然后作为第二步决定如何处理它们。

    int horizontal = Input.GetKeyDown(KeyCode.A) 
     + Input.GetKey(KeyCode.LeftArrow) 
     + Input.GetAxis("Horizontal") > 0.2f ? 1:0 
     - Input.GetKey(KeyCode.D) 
     - Input.GetKey(KeyCode.RightArrow) 
     - Input.GetAxis("Horizontal) < 0.2f ? 1:0;
    horizontal = Mathf.Clamp(horizontal, -1,1);
    

    好的,现在您在这一帧中有一个值为 -1、0 或 1 的值。接下来你必须决定你的玩家是否会移动。如果你想处理重复的动作,通常你会在支持操纵杆控制器的情况下这样做。通常我这样做的方式是在角色控制器类中有一个变量,该变量会记住您上次移动的时间,并且仅在重复持续时间到期时才允许您移动。

    private float _lastMoveTime = 0.0f;
    private float const kMinMoveTime = 0.1f;  // in seconds
    
    ...
    if (Time.runtimeSinceStartup - _lastMoveTime > kMinMoveTime)
    {
        if (horizontal==-1 || horizontal==1)
        {
            _lastMoveTime = Time.runtimeSinceStartup;
            // move according to horizontal
        }
    }
    

    最后,您想检测何时有人释放键,并重置计时器。这样做意味着如果按住多个键,您会立即获得响应,但即使在单键按住的情况下,您也无需等待重复按下同一个按钮。

    if (Input.GetKeyUp(KeyCode.A)
     || Input.GetKeyUp(KeyCode.LeftArrow) 
     || Input.GetKeyUp(KeyCode.D) 
     || Input.GetKeyUp(KeyCode.RightArrow))
    {
        _lastMoveTime = 0.0f;
    }
    

    请注意,如果您总是希望在移动之间强制延迟,您可以用Time.realtimeSinceStartup - kTimeBetweenMoves 代替上面的0.0f,并且您在按下和释放之间有准确的时间。

    
    Hope this helps.
    

    【讨论】:

      【解决方案4】:

      使用 Unity 的新输入系统并使用左箭头和 A 键创建一个新动作。您可以订阅更改车道的操作。这将同时检查两个键。

      【讨论】:

        猜你喜欢
        • 2017-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-09
        • 2021-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多