如何从 OnTriggerStay 协程中启动和停止其他协程
Posted
技术标签:
【中文标题】如何从 OnTriggerStay 协程中启动和停止其他协程【英文标题】:How to start and stop other coroutines from a OnTriggerStay coroutine 【发布时间】:2021-10-24 00:42:50 【问题描述】:我对编程很陌生,所以我很喜欢任何帮助。
这在 theory 中应该可以工作,但由于某种原因,当我在 unity 中运行它时,它就是不工作,我不知道 为什么.
我希望这个伤害系统能够工作,但我希望SFX和伤害率是不同但是我不知道该怎么做,这是我能想到的最好的。
问题: 尽管它确实会造成伤害,但它会反复叠加伤害。当我不应该受到伤害时,它不会因为某种原因而停止。
IEnumerator OnTriggerStay2D(Collider2D collision)
if (collision.CompareTag("Damage"))
//The StopCoroutine here is supposed to stop it from stacking however I am getting
//mixed results
StopCoroutine(Damager());
StopCoroutine(DamageSFX());
StartCoroutine(Damager());
StartCoroutine(DamageSFX());
//I feel like it should be an "else if" method but I'm not sure why or how
else
StopCoroutine(Damager());
StopCoroutine(DamageSFX());
yield return new WaitForEndOfFrame();
IEnumerator Damager()
while (true)
curruntHealth--;
yield return new WaitForSeconds(Delay);
IEnumerator DamageSFX()
while (true)
//This part works perfectly fine on its own but not in this context
FindObjectOfType<AudioManager>().Play("Damage SFX");
yield return new WaitForSeconds(SoundDelay);
【问题讨论】:
为什么要重新启动例程每个 FixedUpdate 调用? 最后的yield return new WaitForEndOfFrame();
也没什么用;)
@derHugo lel good one...如果我不知道更好的话,我的电脑会崩溃
那么 .. 随心所欲 ... 我只能告诉你的是,它在你拥有它的地方绝对不会做任何事情 ... 没有无限循环可能会冻结你的应用程序,并且可以肯定它不会“让你的电脑崩溃”^^ 如果你这么信任这个页面上的人,那么为什么还要在这里问呢? ^^
@derHugo 啊等等,我明白你的意思了,对不起,我以为你在谈论不同的东西
【参考方案1】:
你已经接近了,但这里有几件事要看看。
首先 - 您可能需要一个简单的 bool 标志 来检查您是否启动了破坏性协程,这将阻止它们被重复创建。在您发布的示例中,您希望在 OnTriggerExit2D(Collider2D other)
中连接 Stop第二 - 当您使用我相信您必须参考的方法启动一个 couroutine 时,您必须停止它。如果您改用字符串,它会更容易停止。 example of ref to couroutine and string calls
这里有一个示例,可以满足您的需要。代替 OnTriggerStay,我只使用了一个可以在检查器中切换的公共 bool。
public bool iscolliding;
float delay = 1f;
float sounddelay = 3f;
bool takingDamage = false;
// ref to started coroutine for start/stop if you didn't want to use strings
// private IEnumerator damageCoroutine;
private void Update()
// we have a collision
// this would be OnTriggerStay2D
if (iscolliding)
// and we haven't stared our couroutines up
if (!takingDamage)
StartCoroutine("Damager");
StartCoroutine("DamageSFX");
takingDamage = true; // flag on
// else no collision
// so check on OnTriggerExit2D
else
// we're still taking damage, so stop the coroutines
if (takingDamage)
StopCoroutine("Damager");
StopCoroutine("DamageSFX");
takingDamage = false; // flag off
IEnumerator Damager()
while (true)
Debug.Log("Taking damage");
yield return new WaitForSeconds(delay);
IEnumerator DamageSFX()
while (true)
//This part works perfectly fine on its own but not in this context
Debug.Log("Play damage sound fx");
yield return new WaitForSeconds(sounddelay);
`
【讨论】:
非常感谢!我最终使用了我不喜欢的字符串方法。但是,它有效,现在我只关心 lel。【参考方案2】:好的 所以我得到的答案确实使用 string 方法 来启动协程 我 不喜欢 但 它确实有效
感谢@RichardSoluis
[SerializeField] float Delay;
[SerializeField] float SoundDelay;
private bool IsTakingDamage = false;
void OnTriggerStay2D(Collider2D collision)
if (collision.CompareTag("Damage") && !IsTakingDamage)
StartCoroutine("Damager");
StartCoroutine("DamageSFX");
IsTakingDamage = true;
void OnTriggerExit2D(Collider2D collision)
if (collision.CompareTag("Damage") && IsTakingDamage == true)
StopCoroutine("Damager");
StopCoroutine("DamageSFX");
IsTakingDamage = false;
IEnumerator Damager()
while (true)
curruntHealth--;
yield return new WaitForSeconds(Delay);
IEnumerator DamageSFX()
while (true)
FindObjectOfType<AudioManager>().Play("Damage SFX");
yield return new WaitForSeconds(SoundDelay);
【讨论】:
以上是关于如何从 OnTriggerStay 协程中启动和停止其他协程的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程协程中的多路复用技术 ① ( 多路复用技术 | await 协程多路复用 | Channel 通道多路复用 )