[英]How do I get the for loop to only loop every time the player presses Z
I am trying to cycle through a list of dialogue to update a text component.我正在尝试循环浏览对话列表以更新文本组件。
The var i
is only supposed to increases when the player presses z but every time I try the var i
increases to the max value instead of once every time I press Z. var
i
应该只在玩家按下 z 时增加,但每次我尝试 var i
增加到最大值而不是每次我按下 Z 时增加一次。
IEnumerator gameDialog ( )
{
while ( i < prologueDialog.Count )
{
PlayerPrefs.SetInt ( "StoryProgress(Prologue)", i );
currentListIndex = PlayerPrefs.GetInt ( "StoryProgress(Prologue)" );
if ( i == 0 )
{
dialogText.text = prologueDialog [ 0 ];
}
if ( Input.GetKey ( KeyCode.Z ) )
{
pressedZ = true;
dialogText.text = "";
dialogText.text = prologueDialog [ i ];
}
yield return new WaitUntil ( ( ) => pressedZ );
pressedZ = false;
oldi = i;
i++;
if ( oldi + 1 != i )
{
i = oldi + 1;
}
Debug.Log ( i );
}
}
I've tried everything I could think of using yield
, WaitUntil
, WaitForSeconds
, bool
values to stop the if statement from running more than once.我已经尝试了所有我能想到的使用
yield
、 WaitUntil
、 WaitForSeconds
、 bool
值来阻止 if 语句多次运行的方法。
Input.GetKey
will return true while the key is held down . Input.GetKey
将在按住该键时返回 true。 What you're after is likely Input.GetKeyDown
which returns true during the frame it's initially pressed, and will not return true until the same key has been released.您所追求的可能是
Input.GetKeyDown
,它在最初按下的帧中返回 true,并且在释放相同的键之前不会返回 true。
The WaitUntil
IEnumerator
causes the code execution to pause at that spot, until the function predicate returns true. WaitUntil
IEnumerator
导致代码执行在该点暂停,直到函数谓词返回 true。 What that means in layman's terms is that the code is going to stop on that line, and move no further, until pressedZ
somehow becomes true.用外行的话来说,这意味着代码将停在那条线上,不再移动,直到
pressedZ
以某种方式变为真。 But, given that the code won't progress, you can start to see that the keys aren't ever read again, and therefore, pressedZ
will never become true.但是,鉴于代码不会继续,您可以开始看到键不再被读取,因此
pressedZ
永远不会变为真。
One thing to note is that saving any game state to the PlayerPrefs
is almost universally frowned upon.需要注意的一件事是,将任何游戏状态保存到
PlayerPrefs
几乎是普遍不赞成的做法。 But that's another issue that can be resolved after getting your dialogue running.但这是另一个可以在对话运行后解决的问题。
Instead of trying to poll your keyboard input in a "coroutine", might I suggest you use the already available Update
method to use as your frame based polling mechanism?我建议您使用已经可用的
Update
方法作为基于框架的轮询机制,而不是尝试在“协程”中轮询您的键盘输入? It also still includes the PlayerPrefs
persistence, which I would suggest replacing at your earliest convenience.它还包括
PlayerPrefs
持久性,我建议您尽早更换。 This has been written, but not tested.这已被写入,但未经测试。
public class Test : MonoBehaviour
{
[SerializeField] private TextMeshPro dialogText;
private List<string> _dialoguePhrases = null;
private string _storyName;
private int _dialogueIndex = 0;
private void Awake ( )
{
HideDialogue ( );
}
public void ShowDialogue ( List<string> dialoguePhrases, string storyName = "StoryProgress(Prologue)" )
{
_dialogueIndex = PlayerPrefs.GetInt ( storyName, 0 );
// check the saved progress index with the newly passed in dialoguePhrases (or -1 if null).
if ( _dialogueIndex >= ( dialoguePhrases?.Count ?? -1 ) )
{
HideDialogue ( );
return;
}
_dialoguePhrases = dialoguePhrases;
_storyName = storyName;
dialogText.text = dialoguePhrases [ _dialogueIndex ];
enabled = true; // Lets the Update method run.
}
public void HideDialogue ( )
{
_dialoguePhrases = null;
_dialogueIndex = 0;
dialogText.text = string.Empty;
enabled = false; // Stops the Update method from being called.
}
private void Update ( )
{
if ( Input.GetKeyDown ( KeyCode.Z ) && _dialoguePhrases != null )
{
if ( ++_dialogueIndex < _dialoguePhrases.Count )
{
dialogText.text = _dialoguePhrases [ _dialogueIndex ];
PlayerPrefs.SetInt ( "StoryProgress(Prologue)", _dialogueIndex );
}
else
{
// You've clicked on the last one, and now you need to do something after the dialogue has finished.
HideDialogue ( );
}
}
}
}
The idea here is that you send through a list of dialogue phrases, and a name (id) of where the dialogue state would be persisted (preferably not in the PlayerPrefs).这里的想法是你发送一个对话短语列表,以及一个对话状态将被持久化的名称(id)(最好不在 PlayerPrefs 中)。
The Update
method is then enabled, when the component itself has it's enable
flag set to true.当组件本身将其
enable
标志设置为 true 时,将启用Update
方法。 The normal checks are made in Update
, and when the end of the dialogue is reached, the component turns itself off waiting for the next show dialogue command.正常检查在
Update
中进行,当对话结束时,组件将自行关闭,等待下一个显示对话命令。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.