为什么getkeydown会多次开火? (Unity,c#)

时间:2016-06-18 10:28:00

标签: c# unity3d input

我试图通过this course over on Udemy.com自学C#和Unity知识。 在第一个例子中,创建了一个非常基本的文本冒险。 现在从头开始,我使用了相同的游戏结构,试图重新创建我自己的版本,我遇到了一个问题:

Input.GetKeyDown(KeyCode.R)

连续多次激活,我几小时内找不到解决方案。 这是代码的相关部分:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class TextEngine : MonoBehaviour {
public Text myText; 
private int oxygen;


private enum States
{
    wakeup, window_0, room_1, corridor_1, corridor_left,
    corridor_right, corridor_right_left, locked_supply_door,
    damaged_supply_door, supply_door_keypad
} 
private States myState;

// Use this for initialization
void Start() {        
    myState = States.wakeup;                                           
}





// Update is called once per frame
void Update()
{

    // Basic gameplay loop:
    //if myState equals scenario a, then call method a
    if (myState == States.wakeup)                   wakeup();
    if (myState == States.room_1)                   room1();
    if (myState == States.corridor_1)               corridor_1();
    if (myState == States.corridor_right)           corridor_right();
    if (myState == States.locked_supply_door)       locked_supply_door();

}



void wakeup()
{
    oxygen = 100;
    myState = States.room_1;
}


void room1()
{
    myText.text = "Oxygen Level: " + oxygen + "\n\nYou wake up. Press W to see Window. "
                    +"Press C to go down the Corridor.";

    if (Input.GetKeyDown(KeyCode.W))
    {
        myState = States.window_0;
    }
    else if (Input.GetKeyDown(KeyCode.C))
    {
        myState = States.corridor_1;
    }


}




void corridor_1()
{

    myText.text = "Oxygen Level: " + oxygen + "\n\nYou walk the corridor to the end."
                 + "You can turn Left or Right.\nFrom the Left you hear two gun shots!"
                 +"\nFrom the Right side comes an eerie silence."
                 + "\n\nPress L to turn Left, R to turn Right. Press B to go Back.";
    if (Input.GetKeyDown(KeyCode.L))
    {
        myState = States.corridor_left;
    }
    else if (Input.GetKeyDown(KeyCode.R))
    {
        print("R1");
        myState = States.corridor_right;
    }
    else if (Input.GetKeyDown(KeyCode.B))
    {
        print("B");
        myState = States.room_1;
    }
}



void corridor_right()
{

    myText.text = "Oxygen Level: " + oxygen + "\n\nAnother T-junction!\n"
                 + "You can turn Left or Right.\nFrom the left you still hear nothing."
                 + "\nFrom the Right side you hear a deep and frightening buzz!"
                 + "\n\nPress L to turn Left, R to turn Right. Press B to go Back.";
    if (Input.GetKeyDown(KeyCode.L))
    {
        myState = States.corridor_right_left;
    }
    else if (Input.GetKeyDown(KeyCode.R))
    {
        print("R2");
        myState = States.locked_supply_door;
    }
    else if (Input.GetKeyDown(KeyCode.B))
    {
        print("B");
        myState = States.corridor_1;
    }

}





void locked_supply_door()
{
    myText.text = "Oxygen Level: " + oxygen + "\n\nYou stand in front of a rusty metal door. You step closer. At eye-level there is a dusty sign, "
                 + "barely readable. You wipe off the dust. It reads: 'Supply Room'. Maybe you can find some Oxygen tanks and "
                 + "some communication devices in there?"
                 + "\n\nPress S to Search for a handle."
                 + "\n\nPress R to Ram the door, it looks weak!\n\n"
                 + "Press B to go Back.";
    if (Input.GetKeyDown(KeyCode.S))
    {
        myState = States.supply_door_keypad;
    }
    else if (Input.GetKeyDown(KeyCode.R))
    {
        print("R3");
        myState = States.damaged_supply_door;
    }
    else if (Input.GetKeyDown(KeyCode.B))
    {
        print("B2");
        myState = States.corridor_1;
    }
}

}

我期待发生的事情:

  1. 游戏开始了。 myState = States.wakeup;获得了资格。

  2. wakeup()被调用,myState = States.room_1;通过room1()调用Update(),屏幕上显示文字。

  3. 当按下C键时,room(1)会通过myState = States.corridor_1;来电Update()拨打corridor_1(),然后再次显示该文字。

  4. 到目前为止,一切都按预期工作。但现在出现了问题。 我期待这种行为: 4.A我按下R键,"R1"被打印,通过myState = States.corridor_right;调用corridor_right()等待以获得另一个关键提示。

    但接下来会发生这种情况: 4.BI按下R键,"R1"被打印,并通过myState = States.corridor_right;调用corridor_right(),然后不再输入立即打印"R2"myState = States.locked_supply_door;已执行,通过locked_supply_door()调用Update(),然后立即"R3"打印到控制台,然后更改myState = States.damaged_supply_door;,继续调用通过Update()的方法,但我尚未实施该方法。

    这些步骤似乎正确执行,但GetKeyDown的行为更像是'GetKey'并不喜欢自己!

    为什么GetKeyDown似乎多次被激活,即使它只应该被激活一次?

    人们似乎大多数问题GetKeyDown两次,但不是几次。 一个常见的问题似乎是脚本在Unity中的某个地方被多次连接,而这种情况并非如此:Canvas with Text Field +获取脚本。

    如果你已经做到这一点,我要感谢你已经帮助我的时间。 如果我能解决这个问题,我找不到解决办法!我的橡皮鸭也不能帮助我。

1 个答案:

答案 0 :(得分:1)

问题是你没有用 ELSE 进行“更新”,所以当你从一种状态转换到另一种状态时,它不会等待1帧通过,并且如果你没有等待1帧通过, ,因为你改变并且是正确的,你进入另一个if,并且因为一个框架没有通过直到最后一个R关闭,它仍然会说真的......

因此,在“更新”功能中,使用 ELSE IF 制作它们,而不是所有 IF 。这样,当你输入一个时,如果里面的函数完成,它将通过1帧重新进入。

所以将更新更改为:

void Update()
{

    // Basic gameplay loop:
    //if myState equals scenario a, then call method a
    if (myState == States.wakeup)                        wakeup();
    else if (myState == States.room_1)                   room1();
    else if (myState == States.corridor_1)               corridor_1();
    else if (myState == States.corridor_right)           corridor_right();
    else if (myState == States.locked_supply_door)       locked_supply_door();

}