J'ai des objets avion (comme dans l'avion aérien) dans mon programme, ils sont détruits lorsque les balles les touchent mais ils sont également détruits après 5 secondes, lorsqu'ils sortent de l'écran.
J'ai aussi un script de santé qui se réinitialise le tout quand il descend à 0, et je veux supprimer un point à chaque fois que l'objet est détruit, mais seulement en dehors de l'écran. Donc, je garde les scripts séparés.
J'utilise ceci dans le script de spawn des vaisseaux pour les détruire après 5 secondes, c'est assez simple.
Destroy(spawnedPlane, 5f);
Ce serait parfait si je pouvais juste avoir du code qui fait "Détruire cet objet après X secondes ET l'ajouter à cette valeur". Parce que si je comprends bien, "détruire" n'accepte que 2 paramètres et rien d'autre.
C'est sûrement possible mais je suis perdu. Encore très nouveau à ce sujet. Désolé si ce n'est pas clair mais je sais à peine ce que je fais moi-même.
3 Réponses :
Il suffit d'utiliser une coroutine pour attendre, puis soustraire un point et détruire l'objet en même temps.
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);
}
Si la seule chose que fait la coroutine est d'attendre avant d'exécuter une action, elle doit être remplacée par une instruction Invoke à la place.
Je ne suis pas fan d'invoke car il utilise des chaînes pour trouver des noms de méthodes, ce qui interrompt le changement de nom dans Visual Studio.
Vous pouvez utiliser des événements pour réaliser proprement ce que vous recherchez. Voici un exemple d'événement que vous pourriez trouver utile. D'autres objets peuvent écouter l'événement et une fois qu'il est déclenché, ils seront notifiés.
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();
}
}
Une fois que vous avez défini votre événement, vous pouvez l'ajouter en tant que champ dans votre plan . Une fois que votre avion a été détruit, vous pouvez déclencher l'événement et il en informera à son tour toute personne qui écoute!
public class Score : MonoBehaviour {
public void AddPointsFor (Plane plane) {
Debug.Log("A Plane was destroyed!");
//Tick a counter, add points, do whatever you want!
}
}
Maintenant dans notre classe de score, nous ajoutons un méthode qui sera appelée une fois que l'événement du plan OnDestroyed est déclenché.
public class Plane : MonoBehaviour {
public PlaneEvent OnDestroyed;
public void Destroy () {
Destroy(gameObject);
OnDestroyed.Invoke(this);
OnDestroyed.RemoveAllListeners();
}
}
Une fois que nous avons ces pièces, il est trivial de les fabriquer travailler ensemble. Nous prenons l'avion et nous ajoutons le score en tant qu'auditeur à l'événement OnDestroyed . Ensuite, une fois l'avion détruit, l'événement est déclenché et le score est dit d'ajouter des points.
[Serializable]
public class PlaneEvent : UnityEvent<Plane> { }
Un autre gros avantage à utiliser les événements est que votre avion n'a aucune idée qu'un score égal existe, il permettra à quiconque s'en soucie de savoir qu'il a été détruit. De la même manière, cet événement pourrait également être utilisé pour déclencher des effets de particules, des animations et des effets sonores lorsque l'avion est détruit et tout ce que vous avez à faire est d'ajouter plus d'auditeurs.
+1 pour la réponse détaillée. le mien vient de résoudre le problème, mais vous êtes allés au-delà pour trouver une meilleure solution entièrement!
Si c'était moi, j'irais sûrement avec les événements suggérés par les CaTs.
Coroutine est une autre façon de faire cela, mais les événements sont meilleurs en général au moins dans ce cas. Utiliser également une Coroutine pour un seul Invoke est un peu exagéré (et les Coroutines Unity ne sont pas un peu performantes.) De plus, la Coroutine doit être en dehors de l'objet que vous voulez détruire car les Coroutines Unity meurent lorsque leur MonoBehaviour est détruit.
Si vous n'êtes toujours pas à l'aise avec les événements, vous ...
eh bien, vous devriez le surmonter et les essayer quand même.
Vous pouvez prendre un raccourci que vous pouvez utiliser Coroutine plus efficace - Gratuit .
Et lancez ce code:
Timing.CallDelayed(5f, DestroyAndRemoveHP());
En gros, cela exécutera votre logique avec le délai que vous souhaitez appliquer.
DestroyAndRemoveHP sera votre méthode pour détruire la plate-forme et faire tout ce que vous voulez.
Description complète de la méthode .
Du côté positif, vous commencerez à utiliser MEC qui sont meilleurs que la coroutine unitaire, mais l'apprentissage des événements fait de vous aussi un meilleur programmeur. Vous pouvez faire les deux.