簡體   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