繁体   English   中英

如何让 for 循环仅在玩家每次按下 Z 时循环

[英]How do I get the for loop to only loop every time the player presses 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 );
    }
}

我已经尝试了所有我能想到的使用yieldWaitUntilWaitForSecondsbool值来阻止 if 语句多次运行的方法。

Input.GetKey在按住该键时返回 true。 您所追求的可能是Input.GetKeyDown ,它在最初按下的帧中返回 true,并且在释放相同的键之前不会返回 true。

WaitUntil IEnumerator导致代码执行在该点暂停,直到函数谓词返回 true。 用外行的话来说,这意味着代码将停在那条线上,不再移动,直到pressedZ以某种方式变为真。 但是,鉴于代码不会继续,您可以开始看到键不再被读取,因此pressedZ永远不会变为真。

需要注意的一件事是,将任何游戏状态保存到PlayerPrefs几乎是普遍不赞成的做法。 但这是另一个可以在对话运行后解决的问题。

我建议您使用已经可用的Update方法作为基于框架的轮询机制,而不是尝试在“协程”中轮询您的键盘输入? 它还包括PlayerPrefs持久性,我建议您尽早更换。 这已被写入,但未经测试。

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 ( );
            }
        }
    }
}

这里的想法是你发送一个对话短语列表,以及一个对话状态将被持久化的名称(id)(最好不在 PlayerPrefs 中)。

当组件本身将其enable标志设置为 true 时,将启用Update方法。 正常检查在Update中进行,当对话结束时,组件将自行关闭,等待下一个显示对话命令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM