[英]StartCoroutine is being called so many times (C# Unity)
我在Unity中創建一個彈出菜單選項。 現在我的問題是我在void更新中制作的協程被調用了很多次。 我的意思是,在我的Unity Console上,Debug.Logs正在遞增。 它不應該正確,因為它已經協程了。 可以幫助我了解更多的協程並幫助我解決小問題。
這是我的代碼:
[SerializeField]
GameObject Option;
[SerializeField]
Button btn,btn2;
[SerializeField]
GameObject open, close;
[SerializeField]
GameObject[] opt;
bool startFinding = false;
void Start()
{
Option.SetActive(false);
Button popUp = btn.GetComponent<Button>();
Button popUp2 = btn2.GetComponent<Button>();
popUp.onClick.AddListener(PopUpOption);
popUp2.onClick.AddListener(ClosePopUp);
}
void Update()
{
if (startFinding)
{
StartCoroutine(GameOptions());
}
}
IEnumerator GameOptions()
{
//Get All the tags
opt = GameObject.FindGameObjectsWithTag("MobileOptions");
if (opt[0].GetComponent<Toggle>().isOn == true && opt[1].GetComponent<Toggle>().isOn == true)
{
Debug.Log("Disable first the check box then choose only 1 option between" + "'rendering'"+ "and" + "'livestreaming'");
}
//Livestreaming
if (opt[0].GetComponent<Toggle>().isOn == true)
{
Debug.Log("Livestreaming Activate");
} else
{
Debug.Log("Livestreaming Deactivate");
}
//Rendering
if (opt[1].GetComponent<Toggle>().isOn == true)
{
Debug.Log("Rendering Activate");
} else
{
Debug.Log("Rendering Deactivate");
}
//Fog
if (opt[2].GetComponent<Toggle>().isOn == true)
{
Debug.Log("Fog Activated");
} else
{
Debug.Log("Fog Deactivated");
}
//Camera Effect
if (opt[3].GetComponent<Toggle>().isOn == true)
{
Debug.Log("Camera Effect Activated");
} else {
Debug.Log("Camera Effect Deactivated");
}
yield return null;
}
void PopUpOption()
{
startFinding = true;
//Disable The Mobile Option Button
open.SetActive(false);
//Enable the Close Option Button
close.SetActive(true);
//activate the Mobile Options
Option.SetActive(true);
}
void ClosePopUp()
{
startFinding = false;
//eanble the mobile option button
open.SetActive(true);
//disable the close option button
close.SetActive(false);
//deactivate the Mobile Option
Option.SetActive(false);
}
不要在Update
方法中使用StartCoroutine()
。 在另一種方法中調用它,並在需要的while loop
在coroutine
函數內部使用while loop
。 只需在Update
方法之外控制StartCoroutine()
這是協程的工作方式:
假設我有一個名為MyRoutine的Couroutine函數(在您的情況下,您將其稱為GameOptions)
private IEnumerator MyRoutine()
然后,在我代碼的任何地方,調用
StartCoroutine(MyRoutine));
將像通常的方法一樣簡單地調用MyRoutine
。 因此,如果您在update中調用它,它將像任何方法一樣一直被調用。 這不是您想要的。 使協程與眾不同的是,您可以在協程中使用yield
關鍵字。 有很多方法可以使用它,但是最常用的(也是最簡單的)一種方法是讓yield return null
yield return null
表示“停止此協程,但在下一幀繼續執行”。 您不需要調用任何其他函數(不一定是StartCoroutine)。 執行將在下一幀繼續。
回到您在問題中發布的內容,您在最后寫了yield return null
。 因此,您的方法正在執行,直到最后,才停止並繼續下一幀,但是由於沒有其他事情要做,因此它將在下一幀退出。
使用協程的一種典型方法是在while循環中讓yield return null
,因此當它恢復時,它將繼續循環。 這是一個做到這一點的例子
private IEnumerator MyRoutine()
{
while(running) //running is a member bool that you could set to false to exit
{
// Do all the stuff you want to do in ONE frame
// ...
yield return null;
}
}
通常,將在Start()函數中或稍后在觸發事件時調用StartCoroutine。
如果您想了解更多有關協程的信息,或者檢查您是否正確理解協程,請查看此頁面: https : //docs.unity3d.com/Manual/Coroutines.html
或此視頻https://unity3d.com/learn/tutorials/topics/scripting/coroutines
//編輯:快速顯示一個有用的選項
在上面的代碼段中,while循環與Update函數非常相似(循環內部每幀執行一次)。 一個不錯的選擇是更換
yield return null
通過
yield return new WaitForSeconds(waitTime)
其中waitTime
是您要在恢復之前等待的時間(以秒為單位)
//編輯結束
更新稱為每幀,如果您的條件為真,則在每幀啟動協程。 只需設置您的標志即可加入1次。
void Update()
{
if (startFinding)
{
startFinding = false;
StartCoroutine(GameOptions());
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.