【问题标题】:C# Unity GetKeyDown() not being detected properlyC# Unity GetKeyDown() 未正确检测到
【发布时间】:2018-08-23 08:34:24
【问题描述】:

所以我有一个小雪橇原型。我目前正在编写一些控件来补充我应用的刚体物理。我的目标是在左转或右转的相反方向施加一个力,以获得一种打滑、抓边的效果,然后向前施加一个力来补偿失去的动量。

但是我无法做到这一点,因为无论出于何种原因,我都无法让 GetKeyDown() 或 GetKeyUp() 函数工作。我已经包含了下面的代码。基本上发生的是“按钮释放”。文本不断得到输出,然后偶尔我会得到一个“按下按钮”输出,该输出只发生一次,然后恢复为“释放按钮”。输出。即使这是罕见的。通常我没有得到任何检测的迹象。

我确定我错过了一些微不足道的问题,并且我一直在寻找类似的问题,但似乎没有一个能解决我的问题。如果有人能给我任何想法,我将不胜感激。此外,任何优化提示将不胜感激。我对 C# 和 Unity 还有些陌生。

我正在进行调整和试验,如果我错过了一些不必要的 cmets,我深表歉意。

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class PlayerController : MonoBehaviour
    {

    private Rigidbody rb;
    public bool sidePhysics;
    public bool keyPress;

    // Use this for initialization
    void Awake()
    {
        rb = GetComponent<Rigidbody>();

    }

    // Update is called once per frame
    void FixedUpdate()
    {
        var x = Input.GetAxis("Horizontal") * Time.deltaTime * 50.0f;
        // No vertical controlls for now.
        //var z = Input.GetAxis("Vertical") * Time.deltaTime * 40.0f;


        // Get axis against which to apply force
        var turnAngle = rb.transform.position.x;




        transform.Rotate(0, x, 0);
        //transform.Translate(0, 0, z);


        // Debug to test input detection
        keyPress = Input.GetKeyDown(KeyCode.A);
        Debug.Log("keyPress: " + keyPress);

        // On either right or left key input down, apply force
        // Later once keys are being detected - addForce forward too 
        if (Input.GetKeyDown(KeyCode.LeftArrow) || Input.GetKeyDown(KeyCode.LeftArrow)
           || Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.D))
        {
            Debug.Log("Button pressed. ");

            // Add opposing force proportionate to the degree of the turn
            rb.AddForce((turnAngle * (-x * 10)), 0, 0, ForceMode.Acceleration);
        }
        else
        {
            Debug.Log("Button released.");
        }



        //Debug.Log("RigidBody: " + rb +
        //          "   Rotation: " + x +
        //          "   turnAngle: " + turnAngle);


    }
}

【问题讨论】:

  • GetKeyDown 检查是否在当前帧中按下了按钮,并且由于您使用的是 FixedUpdate,因此您不会在每一帧都运行它。 FixedUpdate 用于物理更新。如果要使用 GetKeyDown,请改用 Update

标签: c# unity3d


【解决方案1】:

如果您想在按键按住时继续执行操作,请使用Input.GetKey 函数。如果您想在按键被按下时执行一次,您可以使用Input.GetKeyDown 函数,因为它只会在按键被释放并再次按下之前评估为真一次。了解两者之间的区别很重要。

现在,要检测按钮何时被释放,在检查Input.GetKey 后不要使用else 语句。你不会得到你想要的效果。要检测按钮何时被释放,请使用Input.GetKeyUp 函数。在此处添加另一个 if 语句。

更像是这样的:

if (Input.GetKeyDown(KeyCode.A))
{
    //KEY PRESSED
}

if (Input.GetKey(KeyCode.A))
{
    //KEY PRESSED AND HELD DOWN
}

if (Input.GetKeyUp(KeyCode.A))
{
    //KEY RELEASED
}

最后,您应该始终检查Update 函数而不是FixedUpdate 函数中的输入。

【讨论】:

    【解决方案2】:

    除了程序员所说的:

    不要在FixedUpdate() 中使用GetKeyDown()(和类似的)

    GetKeyDown() 仅在密钥更改状态时单次更新调用返回true。因为FixedUpdate 定期运行,这可能会导致它错过(运行太晚)以查看密钥更改状态(因为调用了两个Updates:一个是正确的,然后是下一个重置的它再次为假)。

    来自this answerdocs

    您需要从 Update 函数中调用此函数,因为每帧都会重置状态

    关于 Rutter 关于 GetKey() 的评论 [...],我写的关于 GetKeyDown() 的内容对于 GetKey() 仍然适用,尽管文档没有明确说明。

    【讨论】:

    • 愚蠢的事情,但有很大的不同。
    猜你喜欢
    • 2023-03-22
    • 1970-01-01
    • 2022-01-07
    • 2021-04-08
    • 1970-01-01
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    相关资源
    最近更新 更多