我试图通过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;
}
}
}
我期待发生的事情:
游戏开始了。
myState = States.wakeup;
获得了资格。
wakeup()
被调用,myState = States.room_1;
通过room1()
调用Update()
,屏幕上显示文字。
当按下C键时,room(1)
会通过myState = States.corridor_1;
来电Update()
拨打corridor_1()
,然后再次显示该文字。
到目前为止,一切都按预期工作。但现在出现了问题。
我期待这种行为:
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 +获取脚本。
如果你已经做到这一点,我要感谢你已经帮助我的时间。 如果我能解决这个问题,我找不到解决办法!我的橡皮鸭也不能帮助我。
答案 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();
}