问题描述
所以我有一个OnTriggerEnter函数,该函数每隔一秒钟使用协程删除一次运行状况。我想使用OnTriggerExit函数和StopCoroutine停止它。虽然这仅适用于一个gameObject,但由于总是取消“常规”,因此它会与多个对撞机中断。什么是停止协程离开左撞机的最佳方法?我觉得有一个简单的解决方案,但我看不到。
OnTrigger进入/退出
private float delay= 1f;
void OnTriggerEnter(Collider other)
{
Dealdamage(other,delay);
}
private void OnTriggerExit(Collider other)
{
Stopdamage();
}
协程
private Coroutine routine;
private void Dealdamage(Collider col,float damageRate)
{
var health = col.GetComponent<IChangeHealth>();
if (health == null) return;
routine = StartCoroutine((damageEverySecond(health,damageRate)));
}
IEnumerator damageEverySecond(IChangeHealth health,float rate)
{
while (true)
{
health.RemoveHealth(damage);
yield return new WaitForSeconds(rate);
}
}
protected void Stopdamage()
{
StopCoroutine(routine);
}
解决方法
当被提及时,使用Dictionary<Collider,Coroutine>
存储和检索给定对撞机对象的例程:
private float _delay= 1f;
private readonly Dictionary<Collider,Coroutine> _routines = new Dictionary<Collider,Coroutine>();
private void OnTriggerEnter(Collider other)
{
DealDamage(other,_delay);
}
private void OnTriggerExit(Collider other)
{
// pass on the collider reference
StopDamage(other);
}
private void DealDamage(Collider col,float damageRate)
{
// In general don't use null check for types derived from UnityUngine.Object but rather the bool operator
if (!col.TryGetComponent(out IChangeHealth health)) return;
// Check if a routine already exists for this collider
if(_routines.TryGetValue(col,out var routine) && routine != null)
{
// Avoid concurrent routines for the same object
StopCoroutine(routine);
}
// start a routine for this collider and store the reference
routines[col] = StartCoroutine((DamageEverySecond(health,damageRate)));
}
protected void StopDamage(Collider other)
{
// Check if a routine already exists for this collider
if(_routines.TryGetValue(other,out var routine) && routine != null)
{
// if yes stop it
StopCoroutine(routine);
}
}
private IEnumerator DamageEverySecond(IChangeHealth health,float rate)
{
while (true)
{
health.RemoveHealth(Damage);
yield return new WaitForSeconds(rate);
}
}
另请参见