C# OnTiggerStay中的InputGetKeyDown被多次调用

C# OnTiggerStay中的InputGetKeyDown被多次调用,c#,unity3d,C#,Unity3d,我有一个游戏,如果一个看不见的盒子正在触摸一个物体并按下“e”,文本将根据触摸的物体显示。问题是有时(有点随机)它会运行文本三次。我尝试过将inputkey放入更新中,我尝试过一些布尔函数来测试它是否运行过多次,我检查过是否有多个脚本执行此操作,但没有任何效果 private void OnTriggerStay(Collider other) { if (Input.GetKeyDown(name: "e") && other.tag == "Mar Room")

我有一个游戏,如果一个看不见的盒子正在触摸一个物体并按下“e”,文本将根据触摸的物体显示。问题是有时(有点随机)它会运行文本三次。我尝试过将inputkey放入更新中,我尝试过一些布尔函数来测试它是否运行过多次,我检查过是否有多个脚本执行此操作,但没有任何效果

private void OnTriggerStay(Collider other)
{
    if (Input.GetKeyDown(name: "e") && other.tag == "Mar Room")
    {
        switch (other.gameObject.name)
        {
            case "Cushion1":

                other.transform.rotation = Quaternion.Euler(-90, 0, 0);
                other.transform.localPosition = new Vector3(-206.849f, 108.2456f, -48.99983f);
                runSentence("CouchText");
                Debug.Log("I have been called cush");
                items += 1;
                break;
            case "Chair":
                other.transform.rotation = Quaternion.Euler(-90, 0, 90);
                other.transform.localPosition = new Vector3(-182.399f, 108.6756f, -16.16f);
                runSentence("ChairText");
                Debug.Log("I have been called chair");
                items += 1;
                break;
            case "Lamp":
                other.transform.rotation = Quaternion.Euler(-90, 0, 0);
                other.transform.localPosition = new Vector3(-180.779f, 111.3156f, -47.82983f);
                runSentence("LampText");
                items += 1;
                Debug.Log("I have been called lamp");
                break;
            case "Time":
                other.transform.rotation = Quaternion.Euler(0, 90, 0);
                other.transform.localPosition = new Vector3(-178.499f, 110.5756f, -37.59983f);
                runSentence("HourglassText");
                items += 1;
                Debug.Log("I have been called time");
                break;
            case "Art":
                other.transform.rotation = Quaternion.Euler(0, 0, 0);
                other.transform.localPosition = new Vector3(-190.499f, 113.3056f, -51.31983f);
                runSentence("PictureText");
                items += 1;
                Debug.Log("I have been called art");
                break;

            default:
                break;
        }
    }
}

如果您可能正在与多个触发器交互,您可能会遇到一个问题,即可以多次调用on-trigger-stay。 GetKeyDown对于正在查看的整个帧都是正确的,因此如果您将物理刻度设置为高于帧速率,您也将收到多个调用。

永远不要在物理函数中进行输入处理 物理功能以设定的间隔运行,而键盘输入以渲染帧间隔运行(渲染帧间隔不规则,可能比物理步骤长或短,导致输入重复或丢失)

相反,您需要将物理操作的引用保存到标准的
Update()
循环中,在该循环中检查按键并执行操作:

private GameObject nearTo = null

private void OnTriggerStay(Collider other) {
    if (other.tag == "Mar Room") {
        nearTo = other.gameObject;
    }
}

private void Update() {
    if(nearTo != null && Input.GetKeyDown(name: "e")) {
        //do stuff
        nearTo = null; //set to null when we're done
    }
}

另外,我不认为
Input.GetKeyDown(name:“e”)
是有效的代码,但这可能是为了我们的方便而编辑的,而不是为了实际实现。

这是迄今为止最容易理解的解决方案。我是Unity的新手,你能解释一下我将如何改变帧速率吗?我假设它是Time Manager中的Fixed Timestep选项,但我不确定如何调整它。另一个答案是避免更改时间刻度的正确方法,如果您想执行诸如慢速mo等操作,这很有用。但是,是的,Fixed Timestep是物理刻度,您很少想更改它,但是越小,一切都会越快,越大,一切都会越慢。至于帧速率,除了设置它的最大速度(通常设置为60fps)之外,你无法控制它。看到这种代码在物理回调函数中处理输入是很奇怪的,但原因是人们把它作为答案,而且它实际上会得到很多的提升。其他新用户看到了它,也跟着它去了。@Programmer是的,我每天都要在Minecraft Forge论坛上与十几种不同的货物崇拜行为作斗争。最让我恼火的是
IHasModel
这个概念,一个半新的程序员使用它制作了一个教程(为了向它投射项目/块,以便调用
registerModel()
,它只是将公共信息传递给外部方法…)