第一个解决方案 - 延迟实例化和销毁
如果我理解正确的话,闪电游戏对象已经是你在触发时实例化的预制件,并且你想在延迟后销毁它。
因此,与其使用协程解决方案并启用或禁用对象,不如在实际调用脚本后使用实例化和销毁更简单:
GameObject obj = GameObject.Instantiate(yourPrefab, position, rotation);
GameObject.Destroy(obj, delay);
只要您将yourGameObject 提供给调用类,就可以从任何地方调用此函数。所以你甚至不需要一个自己的类。
第二个浮点参数是以秒为单位的延迟(参见API)
例如,你可以有一个射击类:
public class Shooting : MonoBehavior
{
[SerializeField]
private GameObject lightningPrefab;
[SerializeField]
private float delay;
public void OnShooting(Vector3 position, Quaternion rotation){
GameObject obj = GameObject.Instantiate(lightningPrefab, position, rotation);
/* Directly after instantiating the Object
* you can already "mark" it to be destroyed after x seconds
* so you don't have to store it as variable anywhere */
GameObject.Destroy(obj, delay);
}
}
然后您还可以添加一些检查以不经常生成预制件:
[...]
private GameObject lightningObject;
public void OnShooting(Vector3 position, Quaternion rotation){
if(lightningObject == null ){
lightningObject = GameObject.Instantiate(lightningPrefab, position, rotation);
GameObject.Destroy(lightningObject, delay);
}
}
这样一来,您的闪电对象一次总是只有一个。
第二种解决方案 - 超时
另一种不必一直实例化和销毁对象的方法是简单的超时而不是协程:
public class Shooting : MonoBehavior
{
[Tooltip("The lightning Object")]
[SerializeField]
private GameObject lightningObject;
[Tooltip("The time in sec the lightningObject stays visible")]
[SerializeField]
private float visibleDelay;
/* track the time that passed since the last OnShooting call */
private float timePassed;
/* Additional bool to not perform Update when not needed */
private bool isVisible;
/* Update is called once each frame */
private void Update(){
/* If the object is not visible do nothing */
if (isVisible != true) return;
/* update the timePassed */
timePassed += Time.deltaTime;
/* if delay passed since last OnShooting call
* deactiavte the object */
if (timePassed >= visibleDelay){
lightningObject.SetActive(false);
}
}
public void OnShooting(){
/* Activate the Object */
lightningObject.SetActive(true);
/* set isVisible */
isVisible = true;
/* reset the timePassed */
timePassed = 0;
}
}