等待协程完成 [英] Wait for coroutine to finish
问题描述
我有一个协程,在 N
秒后清除文本并将其恢复为原始形状.问题是协程在首次返回(等待几秒钟
)之后再也不会继续.
I have coroutine that after N
seconds clear text and returns it to it's original shape. Problem is that coroutine never continues after first return (wait for seconds
).
我在其他地方遇到了这个问题,并想出了发生的原因,因为我在协程完成之前就销毁了Gameobject,所以我让它返回了bool,但是现在我很困惑,在这里不能使用相同的技巧,因为我是通过脚本启动协程的,未初始化.该脚本仅具有静态功能,通过它我可以启动协程.这是我的代码:
I had this problem somewhere else and figured it out that is happening because i destroy Gameobject before coroutine finish so i made it return bool but now i am confused and can not use same trick here since i am starting coroutine through script that is not initialized. That script only has static function through which i start coroutine. Here is my code:
void OnMouseDown()
{
bool safeDestroy = false;
IGatherable gather = CharacterCommands.character.GetComponent<IGatherable>();
if(gather != null)
{
switch(itemID)
{
case 3:
Drops[] d = ChestDrop.GetItemFromDropStash(drops, gather, this); //Here is function that is starting function with coroutine PROBLEM
if(d.Length == 0)
{
safeDestroy = true;
}
else
{
drops = d;
}
break;
default:
if(ItemDatabase.GetItem(itemID).maxStackable < Inventory.GetCoins() + amount)
{
Parameters.centerText.text = "Not enough space in your bag!";
safeDestroy = Parameters.clearText(Parameters.centerText, 3, this); //Coroutine i had same problem but done it this way.
}
else
{
gather.GatherItem(itemID, amount);
safeDestroy = true;
}
break;
}
}
if(safeDestroy)
{
Destroy(this.gameObject);
}
}
这是函数本身:
public static Drops[] GetItemFromDropStash(Drops[] drops, IGatherable gather, MonoBehaviour justToStartCoroutine)
{
foreach(Drops drop in drops)
{
int r = UnityEngine.Random.Range(1, 101);
if(r < drop.chance)
{
if(ItemDatabase.GetItem(drop.itemID).maxStackable > Inventory.GetItemFromInventoryById(drop.itemID).amount + drop.amount)
{
Inventory.AddItemToInventory(drop.itemID, drop.amount);
Parameters.centerText.text = "+" + drop.amount + " " + ItemDatabase.GetItem(drop.itemID).itemName;
switch(ItemDatabase.GetItem(drop.itemID).itemRarity)
{
case ItemRarity.common:
Parameters.centerText.color = Color.gray;
break;
case ItemRarity.normal:
Parameters.centerText.color = new Color(80, 100, 255);
break;
case ItemRarity.rare:
Parameters.centerText.color = new Color(255, 80, 80);
break;
case ItemRarity.special:
Parameters.centerText.color = new Color(200, 0, 220);
break;
case ItemRarity.legacy:
Parameters.centerText.color = new Color(199, 224, 0);
break;
case ItemRarity.legendary:
Parameters.centerText.color = new Color(224, 169, 0);
break;
}
bool t = Parameters.clearText(Parameters.centerText, 3, justToStartCoroutine);
int i = Array.IndexOf(drops, drop);
List<Drops> tmp = new List<Drops>(drops);
tmp.RemoveAt(i);
drops = tmp.ToArray();
}
else if (Inventory.CheckForFreeSpaceInInventory() == true)
{
Inventory.AddItemToInventoryToNewSlot(drop.itemID, drop.amount);
Parameters.centerText.text = "+" + drop.amount + " " + ItemDatabase.GetItem(drop.itemID).itemName;
switch(ItemDatabase.GetItem(drop.itemID).itemRarity)
{
case ItemRarity.common:
Parameters.centerText.color = Color.gray;
break;
case ItemRarity.normal:
Parameters.centerText.color = new Color(80, 100, 255);
break;
case ItemRarity.rare:
Parameters.centerText.color = new Color(255, 80, 80);
break;
case ItemRarity.special:
Parameters.centerText.color = new Color(200, 0, 220);
break;
case ItemRarity.legacy:
Parameters.centerText.color = new Color(199, 224, 0);
break;
case ItemRarity.legendary:
Parameters.centerText.color = new Color(224, 169, 0);
break;
}
bool t = Parameters.clearText(Parameters.centerText, 3, justToStartCoroutine);
int i = Array.IndexOf(drops, drop);
List<Drops> tmp = new List<Drops>(drops);
tmp.RemoveAt(i);
drops = tmp.ToArray();
}
else
{
Parameters.centerText.text = "Not enough space in inventory!";
bool t = Parameters.clearText(Parameters.centerText, 3, justToStartCoroutine);
}
}
}
return drops;
}
我该如何实现,直到协程完成后我的物品(在 OnMouseDown()
所在的位置)才能销毁?
How can i achieve so that my item (where OnMouseDown()
is) doesn't destroy until coroutine is finished?
推荐答案
如果要等待协程完成...则该方法也必须是协程.
If you want to wait for a coroutine to finish...then the method must also be a coroutine.
根据具体情况,您有3种选择:
You have 3 options, depending on your specific scenario:
- 将需要等待的代码移到现有的协程方法中(在最后一个当前
yield
之后).- 您还可以将委托传递给当前的协程,并将其用作回调,然后对现有协程的每次使用都可以提供自己的回调委托.然后,等待完成"代码进入该委托中.
这篇关于等待协程完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!