Jump to content
Unity Insider Forum

Animation abspielen bei Objektzerstörung


SyntaxTalkstoMe

Recommended Posts

Guten Morgen zusammen,

ich bin neu im Forum und in Unity und habe eine dringende Frage :)

Ich probiere mich gerade an einem Space Shooter.

Jetzt hätte ich gerne, dass, wenn ein Asteroid zerstört wird, eine Feuerexplosion (Animation) abgespielt wird.

Ich hatte gegoogelt, allerdings hat nichts wirklich geholfen. Das vielversprechendste war das hier:

public Animation ani;  // Use this for initialization

private void Start() 
{
  ani = GetComponent<Animation>();

  if (!ani.isPlaying)
  {
    ani.Play();
  }
}

Wenn ich das allerdings meinem Asteroiden-Prefab als Skript hinzufüge, ist Slot im Inspektor ausgegraut.

Ich habe auch mal dieses Video hier probiert: https://unity3d.com/de/learn/tutorials/projects/space-shooter-tutorial/explosions

Nachdem ich mich an den Code aus dem Video gehalten habe, war es mir ebenfalls nicht möglich, etwas in diesen "Slot" im Inspector reinzuschieben.

Ich habe auch langsam das Gefühl, dass es evtl an der Animation liegt. Aber ich sehe darin nichts verwerfliches (Das Animationssymbol ist rechteckig mit einem Kreis darin der vorne das "Play"-Zeichen hat).

Hat jemand einen nützlichen Tipp oder kann mir sagen, wie ich dies am besten umsetze?

 

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, ich bin noch nicht so weit, dass ich Code wie ein Buch lesen kann, möchte aber versuchen zu helfen.
Du versuchst auf die Anmation zuzugreifen, welche zum zerstörten Asteroiden gehört (unabhängig, ob diese im Inspector angeraut ist oder nicht). Im Video wird kurz vor der Zerstörung des Asteroiden jedoch ein anderes Game Objekt (die Explosion) in die Szene geladen, mit dem Befehl "Instantiate...".

Ich mache es bei mir so wie im Video (stark verkürzster Code von meinem Skript):

public class HealthAndDam : MonoBehaviour
{
    public GameObject explosion;
    public Transform shotSpawn;
    
    void OnTriggerEnter(Collider other)
    {
            IsDead();
    }

    void IsDead()
    {
        Instantiate(explosion, shotSpawn.position, shotSpawn.rotation);
        Destroy(gameObject);
    }
}

Zuerst lege ich als GameObjekt "explosion" die Explosion fest. Diese passiert im Inspector. Dieses ist ein komplet eigenes GameObjekt / Prefab.
Danach lege ich mit "shotSpawn" den Startpunkt der Explosion fest. Auch im Inspector. Dieses ist nichts anderes als der Asteroid.

Bei der Abfrage des Collider des Asteroiden löse ich "IsDead" aus.

In "IsDead" wird zuerst die "explosion" an der "shotSpawn" Position und Drehung neu eingeladen.
Danach wird dieses (also der Asteroird) GameObject zerstört. Die neu in die Szene geladene Explosion bleibt aber erhalten, da es ein anderes Game Objekt ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo nochmal,

danke für deine Antwort. Aber das Problem mit der Animation bleibt nach wie vor. 

Ich hab mal ein Screenshot gemacht. Unten ist auch eine Meldung, die dich aber nicht richtig deuten kann.

Ich kann die ExplosionsAnimation nicht in dieses Feld per Drag& Drop reinverschieben. Es ist zum Mäusemelken. Ich hänge jetzt schon sehr lange an diesem Problem.

Ich kann alles mögliche in dieses graue Feld schieben. Nur nicht die Animation. Ich muss ihm ja sagen, welche Animation er abspielen soll :)

 

Vielleicht gehe ich auch die Sache falsch an. Bin wirklich sehr neu in Unity. Hab davor nur etwas in C# gemacht.  Ich habe zu Testzwecke ein Asteroid auf die Spielfläche gemacht. Dem habe ich dieses Script, dass du oben gepostet hast, hinzugefügt. Natürlich auch ein Rigidbody und Boxcollider2D.

 

Gruß

problem.PNG

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi, zu deiner Fehlermeldung:
Die besagt nur, das in dem angegebenen Script in Zeile 21 eine Klammer "}" zu viel existiert.

Das kann mal passieren, wenn man ganze Codeblöcke kopiert. Überprüf mal den Syntax in den Zeilen davor oder in der gesamten betreffenden Funktion.
Wenn du solche Fehler nicht beseitigst, weigert sich Unity zu laufen 🙁.

Dein anderes Problem hat wohl mit dem Object-Typ zu tun.
Deine Public-Variable ist vom Typ "GameObject" und deine Animation vom Typ "Animation". Das passt leider nicht.

Erstell dir ein Empty-GameObject, häng die Animation dran und speichere es als Prefab ab. Dieses kannst du dann problemlos in den Slot ziehen 🙂.

 

Edit:
Jetzt habe ich mich dummerweise auf das Script von KaBau bezogen.
In deinem ersten Post steht ja schon "Animation" (habe ich bei dem "dunklen Skin" dieser Seite gar nicht lesen können). Sorry.
Aber Jörg hat recht. Check mal ob das Problem nach der Fehlerbeseitigung nicht auch weg ist.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo;

Die Fehlermeldung sagt aus das in dem Script eine geschweifte Klammer ( } ) zufiel oder zu wenig vorhanden ist.

Wen du auf die Fehlermeldung in der Console einen Doppelklick machst wird dein Script geöffnet und die vermeintliche stelle Angezeigt.

Erst mal diesen Fehler entfernen und dann überprüfen ob das Problem immer noch vorliegt.

 

Gruß Jog

Ups war wohl einer Schneller.

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke. Jetzt hat es funktioniert, die Animation in das Feld zu ziehen. Das System ist mir noch nicht so 100% sinnig. Aber es entwickelt sich ;)  Unity ist zwar OOP in Reinkultur, aber trotzdem bei den ersten Schritten etwas gewöhnungsbedürftig.

So ich habe nun den Code geändert. Die Animation wird aber leider noch nicht abgespielt.

public class EnemyLifePoints : MonoBehaviour
{

    public int lebensPunkte;
    public EnemyLifePoints lifePoints;
    public Animation explosion;
    public Transform shotSpawn;
    

    private void Start()
    {
        lifePoints.lebensPunkte = 3;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(lifePoints.lebensPunkte < 1)
        {
            IsDead();
        }
    }

    void IsDead()
    {
        Instantiate(explosion, shotSpawn.position, shotSpawn.rotation);
        Destroy(gameObject);
    }
}
 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hm, funktioniert leider auch nicht. Es wird keine Animation abgespielt. Ich hab den Code noch etwas abgeändert, was aber leider auch nicht zum gewünschten Ergebnis führt. Ich habe aber mittels einer Messagebox herausgefunden, dass er gar nicht in den If-Block reinspringt. Das bedeutet, dass er gar nicht merkt, sobald die Lebenspunkte des Asteroiden unter 1 fällt.

Hier ist nochmal der Code:

Die Objekte werden jedenfalls Ordnnungsgemäß zerstört. Es wird lediglich die Animation nicht abgespielt. Allerdings muss ich auch dazu sagen, dass ich noch ein anderes Scripts auf meiner Bullet habe. Die zerstört alles, was kein Spielergeschoss, Spieler oder Wand ist. Evtl sollte ich den Code auf die Bullet packen?

Fragen über Fragen .... :)

public class EnemyLifePoints : MonoBehaviour
{

    public int lebensPunkte;
    public EnemyLifePoints lifePoints;

    public Animation explosion;
    public Transform shotSpawn;
    public Collider2D colli;


    private void Start()
    {
        lifePoints.lebensPunkte = 3;

        OnTriggerEnter2D(colli);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (lifePoints.lebensPunkte < 1)
        {
             EditorUtility.DisplayDialog("asdfa", "asdfasdf", "asdfasd");
           IsDead();
        }
    }

    void IsDead()
    {
        Instantiate(explosion, shotSpawn.position, shotSpawn.rotation);
        explosion.Play();
        Destroy(gameObject);
    }

}

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,
setze mal zu Testzwecken in der Start()-Routine den Lebenswert auf "0" (nicht auf 3).
Dann sollte deine Bedingungsabfrage (wert < 1) auch greifen und deine Routine "IsDead()" aufgerufen werden.

Die andere Möglichkeit wäre "IsDead()" direkt aus der Start()-Routine aufzurufen (zu Testzwecken), um zu schauen wie sie arbeitet.

Gruß TurTur

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wenn du den Space Shooter aus dem Tutorial Video nimmst: die haben nicht eine Animation, sondern ein anderes GameObjekt gespawnt. Irgendwo hat Malzbie mal ein Tutorial zum Thema 2D Shooter gemacht. Er hatte glaube ich auch Animationen genutzt. Ich habe eben auf die Schnelle es nicht gefunden.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 30 Minuten schrieb TurTur:

Die andere Möglichkeit wäre "IsDead()" direkt aus der Start()-Routine aufzurufen (zu Testzwecken), um zu schauen wie sie arbeitet.

oder besser mit "Invoke". Dann siehst du zuerst noch den Asteroiden vor der Zerstörung:

private void Start()
    {
        Invoke("IsDead", 2.0f);
    }

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

1. "OnTriggerEnter2D" wird automatisch aufgerufen, wenn ein "Collider2D " in den Trigger eingetreten ist (nur 2D-Physik) dein Aufruf in der Startmethode 

 OnTriggerEnter2D(colli);

ist falsch.

2. Die Lebenspunkte müssen irgendwo herunter gezählt werden.

3. Wenn du ein GameObject zerstörst und diesem die Animation angehängt ist kann diese nicht mehr ausgeführt werden weil das GameObject nicht mehr existiert.

mit  Destroy(gameObject); wird es sofort zerstört, mit z.b  Destroy(gameObject,3); wird es erst nach 3 Sekunden zerstört der 2. Parameter ist eine Zeit Verzögerung.

Man kann auch erst das GameObject deaktivieren damit es nicht mehr sichtbar ist und nach der Animation das GameObject zerstören.

 

Gruß Jog

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Danke. Ja die Lebenspunkte werden heruntergezählt nachdem eine Bullet den Meteor trifft.

Das mit dem dem zerstörten Gameobject ist mir bewusst. Ich hatte mir diverse andere Tutorials angeschaut und muss sagen, dass dieses von Malzbie sehr gut ist. Ich werde jetzt komplett nochmal neu anfangen. Wenn ich es nachbaue, lerne ich es wie es funktioniert bzw das wie und warum.

Aber danke für die Antworten.

 

Gruß

Link zu diesem Kommentar
Auf anderen Seiten teilen

Archiviert

Dieses Thema ist jetzt archiviert und für weitere Antworten gesperrt.

×
×
  • Neu erstellen...