销毁对象时如何使程序执行某些操作?

时间:2019-05-31 00:54:33

标签: c# unity3d

我的程序中有飞机(就像飞机上一样)对象,当子弹击中它们时它们会被破坏,但是当它们离开屏幕5秒钟后它们也会被破坏。

我还有一个运行状况脚本,当它降为0时,它会重置整个对象,并且我希望每次销毁对象时都删除一个点,但仅限于不在屏幕上时。所以我将脚本分开。

我在飞船生成脚本中使用此命令在5秒后销毁它们,足够简单。

Destroy(spawnedPlane, 5f);

如果我能编写一些代码“在X秒后销毁该对象并将其添加到此值”,那将是完美的。因为据我了解,“ destroy”仅接受2个参数,而没有其他参数。

当然有可能,但我很茫然。对此还是很新的。抱歉,如果还不清楚,但我几乎不知道自己在做什么。

3 个答案:

答案 0 :(得分:4)

您可以使用events轻松实现所追求的目标。以下是一个可能有用的事件示例。其他对象可以监听事件,一旦事件触发,便会得到通知。

[Serializable]
public class PlaneEvent : UnityEvent<Plane> { }

定义事件后,可以将其添加为“飞机”中的字段。一旦飞机被摧毁,您就可以触发该事件,并依次通知正在监听的任何人!

public class Plane : MonoBehaviour {

    public PlaneEvent OnDestroyed;

    public void Destroy () {
        Destroy(gameObject);
        OnDestroyed.Invoke(this);
        OnDestroyed.RemoveAllListeners();
    }

}

现在在我们的得分类中,我们添加了一个方法,一旦触发OnDestroyed平面事件,就会调用该方法。

public class Score : MonoBehaviour { 

    public void AddPointsFor (Plane plane) {
        Debug.Log("A Plane was destroyed!");
        //Tick a counter, add points, do whatever you want!
    }

}

一旦我们拥有了这些作品,让它们一起工作是微不足道的。我们乘飞机,并将比分作为侦听器添加到OnDestroyed事件中。然后,一旦飞机被摧毁,就会触发该事件,并告诉得分增加点数。

public class Game : MonoBehaviour {

    [SerializeField]
    private Score _score;
    [SerializeField]
    private Plane _plane;

    public void Start () {
        // When you are destroyed let me know so I can add some points.
        _plane.OnDestroyed.AddListener(_score.AddPointsFor);
        _plane.Destroy();
    } 
}

使用事件的另一个大优势是您的飞机甚至不知道分数,它会让所有关心的人知道它已经被破坏了。以同样的方式,当飞机被销毁时,此事件还可以用于触发粒子效果,动画和声音效果,而您要做的就是添加更多的侦听器。

答案 1 :(得分:2)

只需使用协程等待,然后减去一个点并同时销毁对象即可。

void Start()
{
    // your startup script
    StartCoroutine(DestroyAfterSeconds(5f));
}

IEnumerator DestroyAfterSeconds(float seconds)
{
    // wait for X amount of seconds before continuing on
    yield return new WaitForSeconds(seconds);

    /*
     *  this runs after the wait.
     *  if the coroutine is on the same gameobject that you are
     *  destroying, it will stop after you run Destroy(), so subtract
     *  the point first.
     * */
    points--;
    Destroy(spawnedPlane);
}

答案 2 :(得分:1)

如果是我,我一定会参加CaTs建议的活动。
协程是这样做的另一种方法,但是至少在这种情况下,事件通常更好。另外,仅将协程用于一次调用就有点过大了(统一协程也不是很好用。)而且,协程必须位于您要销毁的对象之外,因为团结协程在其MonoBehaviour被销毁时会死掉。

如果您对事件仍然不满意,请...
好吧,您应该克服它并尝试使用它们。

您可以选择可以使用More Effective Coroutine - Free的快捷方式。

并启动以下代码:

Timing.CallDelayed(5f, DestroyAndRemoveHP());

基本上,这会延迟您要应用的逻辑。
DestroyAndRemoveHP将是您破坏平台并执行您喜欢的其他任何事情的方法。

Full method description

从好的方面来说,您将开始使用比统一协程更好的MEC,但是学习事件使您也成为一个更好的程序员。您可能两者都做。