调用 OnTriggerStay() 时检查按键

Check key press when OnTriggerStay() is called

我有一个 NPC,当玩家对撞机与 NPC 发生碰撞时,我的玩家可以与之交谈,我使用这段代码来做到这一点:

private void OnTriggerStay2D(Collider2D other)
{
    if (other.gameObject.tag == "InteractiveArea")
    {
        if (Input.GetKeyDown(KeyCode.E))
        {
            Debug.Log("PRESSED NPC");
            CreateAndShowDialog();
        }
    }
}

然而,这确实是随机调用的,有时我第一次按 "E",有时第二次或第三次,依此类推。

我的刚体:

我使用的碰撞器是标准的 BoxCollider2D,我的玩家碰撞器是触发器,NPC 不是。

为什么在 OnTriggerStay 函数中没有检测到某些按键?

OnTriggerStay2D 被随机调用。这就是为什么你不应该检查其中的输入。

OnTriggerEnter2DOnTriggerExit2D 函数中将标志设置为 truefalse 然后检查该标志并在 Update 函数中输入这被称为每一帧。此外,始终使用 CompareTag 而不是 other.gameObject.tag 来比较标签。

private void Update()
{
    if (Input.GetKeyDown(KeyCode.E) && triggerStay)
    {
        //
    }
}

bool triggerStay = false;

void OnTriggerEnter2D(Collider2D collision)
{
    Debug.Log("Entered");
    if (collision.gameObject.CompareTag("InteractiveArea"))
    {
        triggerStay = true;
    }
}

void OnTriggerExit2D(Collider2D collision)
{
    Debug.Log("Exited");
    if (collision.gameObject.CompareTag("InteractiveArea"))
    {
        triggerStay = false;
    }
}

我的猜测是因为 Input.GetKeyDown is only true for the single (Update()) frame that the key was pressed 返回的值,而物理(包括 OnTriggerStay)是在 physics 帧期间调用的,即 FixedUpdate()

我做了一些研究 this question,这表明:

I've been struggling with this issue all afternoon!

My OnTriggerStay and Update/FixedUpdate methods were not in sync resulting is split-second undesired effects.

I finally found the solution when I read in the OnTriggerStay docs that this function can be a co-routine. I simply added a WaitForFixedUpdate in the correct location in my OnTriggerStay and it worked. They now both run in sync with each other. This even corrects the issue in Update.

Another question 将此作为解决方案(程序员的回答):

OnTriggerStay will not call on every frame. One way to get around this is to have OnTriggerEnter, and OnTriggerExit set a bool. Then execute your code in the FixedUpdate().

虽然文档不再说明 this post 所说的内容,

OnTriggerStay gets called every FixedUpdate.

"Note: OnTriggerStay function is on the physics timer so it wont necessary run every frame. "

这证实了我的猜测,文档已更改为不再包含此注释,原因不明。

你可以这样做:

bool eIsOnclick;


 float wait = 0.03f;
    float nextFire = 0.0f;
void Update() {
   if(Input.GetKeyDown(keyKode.E))
      eIsOnclick = true;

else if(nextFire < Time.time)
    nextFire = Time.time + wait;
    ebas = false;

}
void OnTriggerStay2D(Collider2D collision) {
   if(eIsOnclick == true) {
// your cods
}

// 总是不工作的问题