Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Laufzustand | Feindverhalten
Kampfspiel in Unity
course content

Kursinhalt

Kampfspiel in Unity

Kampfspiel in Unity

1. Unity-Animationssystem
2. Spielerverhalten
3. Feindverhalten
4. Spiel Verbessern
5. Verbessere das Flappy Bird Spiel

book
Laufzustand

public abstract class State
{
    public bool isStateFinished;

    public abstract void StartState();
    public virtual void UpdateState()
    {
    }
    public abstract void EndState();
    public virtual void FinishState()
    {
        isStateFinished = true;
    }
}

Änderungen und Ergänzungen

isStateFinished-Variable:

Dies ist eine boolesche Variable, die angibt, ob der Zustand seine Ausführung abgeschlossen hat.

FinishState-Methode:

Dies ist eine neue virtuelle Methode, die isStateFinished auf true setzt. Da sie als virtuell deklariert ist, können abgeleitete Klassen diese Methode überschreiben, falls zusätzliche Aktionen beim Beenden eines Zustands erforderlich sind.

Warum diese Änderungen vorgenommen wurden

Die Änderungen führen die Variable isStateFinished ein, um den Abschluss eines Zustands zu verfolgen, sowie die Methode FinishState, um die Signalisierung des Zustandsabschlusses zu standardisieren. Dadurch können abgeleitete Klassen eigene Logik beim Abschluss eines Zustands hinzufügen.

Run State

public class RunState : State
{
    Rigidbody2D rb;
    Animator animator;
    Transform player;
    float speed;
    Vector2 scale;
    Vector2 velocity;

    public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
    {
        this.animator = animator;
        player = p;
        this.speed = speed;
        this.rb = rb;
        scale = rb.transform.localScale;
        velocity = new Vector2();
    }

    public override void StartState()
    {
        isStateFinished = false;
        animator.SetBool("run", true);
    }

    public override void UpdateState(float DeltaTime)
    {
        scale.x = rb.position.x > player.position.x ? -1 : 1;
        rb.transform.localScale = scale;

        velocity.x = scale.x * speed;
        rb.velocity = velocity;
    }

    public override void EndState()
    {
        animator.SetBool("run", false);
    }
}

Betrachten wir die Klasse RunState, die von der Klasse State erbt. Diese Klasse ist für das Laufverhalten unseres Gegners verantwortlich. Im Folgenden werden die Ergänzungen und Änderungen an dieser Klasse erläutert.

Konstruktor:

public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed);

Dieser Konstruktor initialisiert den RunState mit den erforderlichen Komponenten: einem Rigidbody2D für die Bewegung, einem Animator für Animationen, einem Transform zur Verfolgung des Spielers und einer speed-Variable für die Laufgeschwindigkeit des Gegners;

StartState-Methode:

public override void StartState(); Diese Methode setzt isStateFinished auf false und startet die Laufanimation, indem der boolesche Parameter "run" im Animator auf true gesetzt wird.

UpdateState-Methode:

public override void UpdateState(float DeltaTime); Diese Methode aktualisiert die Position und Ausrichtung des Gegners basierend auf der Position des Spielers; Sie passt die Skalierung des Gegners an, damit dieser dem Spieler zugewandt ist, berechnet die Geschwindigkeit basierend auf dem Wert von speed und wendet diese Geschwindigkeit auf das Rigidbody2D an.

EndState-Methode:

public override void EndState() Diese Methode stoppt die Laufanimation, indem der boolesche Parameter "run" im Animator auf false gesetzt wird.

Funktionsweise für unseren Gegner

  • Bewegung und Animation: Durch die Verwendung von Rigidbody2D und Animator sorgt der RunState dafür, dass sich der Gegner flüssig bewegt und passende Animationen ablaufen. Dies macht das Verhalten sowohl visuell als auch physikalisch realistisch;

  • Verfolgung der Spielerposition: Das player-Transform ermöglicht es dem Gegner, sich stets auf den Spieler zuzubewegen, was für Verfolgungs- oder Laufverhalten essenziell ist;

  • Richtungssteuerung: Die Anpassung von scale.x basierend auf der Position des Spielers stellt sicher, dass der Gegner beim Laufen korrekt zum Spieler ausgerichtet ist, was zur Realitätsnähe beiträgt;

  • Dynamische Zustandsaktualisierung: Die Methode UpdateState wird in jedem Frame aufgerufen, um die Bewegung und Ausrichtung des Gegners kontinuierlich an die Position des Spielers anzupassen. Dadurch reagiert der Gegner dynamisch und flexibel.

Gegner-Initialisierung

private void Start()
{
    idle = new IdleState(animator);
    runState = new RunState(GetComponent<Rigidbody2D>(), animator, player, speed);
    stateManager = new StateManager(idle);

    FarAwayTransition = new Transition(() =>
    {
        return (ThresholdDistance < Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));

    toIdleTransition = new Transition(() =>
    {
        return stateManager.GetCurrentState().isStateFinished;
    }, new StatePourcentage(idle, 100));

    finishRunning = new Transition(() =>
    {
        return (ThresholdDistance >= Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(idle, 100));

    stateManager.AddStateTransition(idle, FarAwayTransition);
    stateManager.AddStateTransition(dashState, toIdleTransition);
    stateManager.AddStateTransition(runState, finishRunning);
}

Erklärung

Initialisierung des Zustands:

Die Variablen idle und runState werden mit ihren jeweiligen Zuständen initialisiert. Die Variable idle ist eine Instanz von IdleState, der der Animator übergeben wird, während runState eine Instanz von RunState ist, die ein Rigidbody2D, einen Animator, ein Transform für den Spieler und einen Geschwindigkeitswert enthält.

Initialisierung des StateManagers:

stateManager = new StateManager(idle); Der StateManager wird mit dem idle-Zustand als Startzustand initialisiert.

Übergangsdefinitionen:

  • FarAwayTransition: FarAwayTransition = new Transition(() => { return (ThresholdDistance < Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));; Dieser Übergang prüft, ob der Spieler weiter als ThresholdDistance entfernt ist;

  • toIdleTransition: toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100)); Dieser Übergang prüft, ob der aktuelle Zustand abgeschlossen ist. Falls ja, erfolgt der Übergang mit 100% Wahrscheinlichkeit in den idle-Zustand.

  • finishRunning: finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100)); Dieser Übergang prüft, ob der Spieler näher als ThresholdDistance ist. Falls ja, erfolgt der Übergang mit 100% Wahrscheinlichkeit in den idle-Zustand.

Hinzufügen von Übergängen zum StateManager:

stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);

Diese Zeilen fügen die definierten Übergänge dem stateManager hinzu.

Warum wir es so gemacht haben

Dynamische Zustandsänderungen:

Die Übergänge ermöglichen es dem Gegner, sein Verhalten dynamisch basierend auf der Position des Spielers und dem Abschlussstatus des aktuellen Zustands zu ändern. Dadurch wird der Gegner reaktiver und interaktiver innerhalb der Spielumgebung.

Bedingte Übergänge:

Der Einsatz von Bedingungen (wie das Überprüfen der Distanz oder des Abschlusses eines Zustands) stellt sicher, dass Zustandswechsel logisch und angemessen erfolgen, was die Realitätsnähe des Gameplays erhöht.

Wahrscheinlichkeitsbasierte Übergänge:

Die Verwendung von StatePourcentage ermöglicht wahrscheinlichkeitsbasierte Übergänge und fügt dem Verhalten des Gegners ein Element von Unvorhersehbarkeit und Vielfalt hinzu.

question mark

Was passiert mit dem animator, wenn die Methode StartState in der Klasse RunState aufgerufen wird?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 5

Fragen Sie AI

expand

Fragen Sie AI

ChatGPT

Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen

course content

Kursinhalt

Kampfspiel in Unity

Kampfspiel in Unity

1. Unity-Animationssystem
2. Spielerverhalten
3. Feindverhalten
4. Spiel Verbessern
5. Verbessere das Flappy Bird Spiel

book
Laufzustand

public abstract class State
{
    public bool isStateFinished;

    public abstract void StartState();
    public virtual void UpdateState()
    {
    }
    public abstract void EndState();
    public virtual void FinishState()
    {
        isStateFinished = true;
    }
}

Änderungen und Ergänzungen

isStateFinished-Variable:

Dies ist eine boolesche Variable, die angibt, ob der Zustand seine Ausführung abgeschlossen hat.

FinishState-Methode:

Dies ist eine neue virtuelle Methode, die isStateFinished auf true setzt. Da sie als virtuell deklariert ist, können abgeleitete Klassen diese Methode überschreiben, falls zusätzliche Aktionen beim Beenden eines Zustands erforderlich sind.

Warum diese Änderungen vorgenommen wurden

Die Änderungen führen die Variable isStateFinished ein, um den Abschluss eines Zustands zu verfolgen, sowie die Methode FinishState, um die Signalisierung des Zustandsabschlusses zu standardisieren. Dadurch können abgeleitete Klassen eigene Logik beim Abschluss eines Zustands hinzufügen.

Run State

public class RunState : State
{
    Rigidbody2D rb;
    Animator animator;
    Transform player;
    float speed;
    Vector2 scale;
    Vector2 velocity;

    public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
    {
        this.animator = animator;
        player = p;
        this.speed = speed;
        this.rb = rb;
        scale = rb.transform.localScale;
        velocity = new Vector2();
    }

    public override void StartState()
    {
        isStateFinished = false;
        animator.SetBool("run", true);
    }

    public override void UpdateState(float DeltaTime)
    {
        scale.x = rb.position.x > player.position.x ? -1 : 1;
        rb.transform.localScale = scale;

        velocity.x = scale.x * speed;
        rb.velocity = velocity;
    }

    public override void EndState()
    {
        animator.SetBool("run", false);
    }
}

Betrachten wir die Klasse RunState, die von der Klasse State erbt. Diese Klasse ist für das Laufverhalten unseres Gegners verantwortlich. Im Folgenden werden die Ergänzungen und Änderungen an dieser Klasse erläutert.

Konstruktor:

public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed);

Dieser Konstruktor initialisiert den RunState mit den erforderlichen Komponenten: einem Rigidbody2D für die Bewegung, einem Animator für Animationen, einem Transform zur Verfolgung des Spielers und einer speed-Variable für die Laufgeschwindigkeit des Gegners;

StartState-Methode:

public override void StartState(); Diese Methode setzt isStateFinished auf false und startet die Laufanimation, indem der boolesche Parameter "run" im Animator auf true gesetzt wird.

UpdateState-Methode:

public override void UpdateState(float DeltaTime); Diese Methode aktualisiert die Position und Ausrichtung des Gegners basierend auf der Position des Spielers; Sie passt die Skalierung des Gegners an, damit dieser dem Spieler zugewandt ist, berechnet die Geschwindigkeit basierend auf dem Wert von speed und wendet diese Geschwindigkeit auf das Rigidbody2D an.

EndState-Methode:

public override void EndState() Diese Methode stoppt die Laufanimation, indem der boolesche Parameter "run" im Animator auf false gesetzt wird.

Funktionsweise für unseren Gegner

  • Bewegung und Animation: Durch die Verwendung von Rigidbody2D und Animator sorgt der RunState dafür, dass sich der Gegner flüssig bewegt und passende Animationen ablaufen. Dies macht das Verhalten sowohl visuell als auch physikalisch realistisch;

  • Verfolgung der Spielerposition: Das player-Transform ermöglicht es dem Gegner, sich stets auf den Spieler zuzubewegen, was für Verfolgungs- oder Laufverhalten essenziell ist;

  • Richtungssteuerung: Die Anpassung von scale.x basierend auf der Position des Spielers stellt sicher, dass der Gegner beim Laufen korrekt zum Spieler ausgerichtet ist, was zur Realitätsnähe beiträgt;

  • Dynamische Zustandsaktualisierung: Die Methode UpdateState wird in jedem Frame aufgerufen, um die Bewegung und Ausrichtung des Gegners kontinuierlich an die Position des Spielers anzupassen. Dadurch reagiert der Gegner dynamisch und flexibel.

Gegner-Initialisierung

private void Start()
{
    idle = new IdleState(animator);
    runState = new RunState(GetComponent<Rigidbody2D>(), animator, player, speed);
    stateManager = new StateManager(idle);

    FarAwayTransition = new Transition(() =>
    {
        return (ThresholdDistance < Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));

    toIdleTransition = new Transition(() =>
    {
        return stateManager.GetCurrentState().isStateFinished;
    }, new StatePourcentage(idle, 100));

    finishRunning = new Transition(() =>
    {
        return (ThresholdDistance >= Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(idle, 100));

    stateManager.AddStateTransition(idle, FarAwayTransition);
    stateManager.AddStateTransition(dashState, toIdleTransition);
    stateManager.AddStateTransition(runState, finishRunning);
}

Erklärung

Initialisierung des Zustands:

Die Variablen idle und runState werden mit ihren jeweiligen Zuständen initialisiert. Die Variable idle ist eine Instanz von IdleState, der der Animator übergeben wird, während runState eine Instanz von RunState ist, die ein Rigidbody2D, einen Animator, ein Transform für den Spieler und einen Geschwindigkeitswert enthält.

Initialisierung des StateManagers:

stateManager = new StateManager(idle); Der StateManager wird mit dem idle-Zustand als Startzustand initialisiert.

Übergangsdefinitionen:

  • FarAwayTransition: FarAwayTransition = new Transition(() => { return (ThresholdDistance < Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));; Dieser Übergang prüft, ob der Spieler weiter als ThresholdDistance entfernt ist;

  • toIdleTransition: toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100)); Dieser Übergang prüft, ob der aktuelle Zustand abgeschlossen ist. Falls ja, erfolgt der Übergang mit 100% Wahrscheinlichkeit in den idle-Zustand.

  • finishRunning: finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100)); Dieser Übergang prüft, ob der Spieler näher als ThresholdDistance ist. Falls ja, erfolgt der Übergang mit 100% Wahrscheinlichkeit in den idle-Zustand.

Hinzufügen von Übergängen zum StateManager:

stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);

Diese Zeilen fügen die definierten Übergänge dem stateManager hinzu.

Warum wir es so gemacht haben

Dynamische Zustandsänderungen:

Die Übergänge ermöglichen es dem Gegner, sein Verhalten dynamisch basierend auf der Position des Spielers und dem Abschlussstatus des aktuellen Zustands zu ändern. Dadurch wird der Gegner reaktiver und interaktiver innerhalb der Spielumgebung.

Bedingte Übergänge:

Der Einsatz von Bedingungen (wie das Überprüfen der Distanz oder des Abschlusses eines Zustands) stellt sicher, dass Zustandswechsel logisch und angemessen erfolgen, was die Realitätsnähe des Gameplays erhöht.

Wahrscheinlichkeitsbasierte Übergänge:

Die Verwendung von StatePourcentage ermöglicht wahrscheinlichkeitsbasierte Übergänge und fügt dem Verhalten des Gegners ein Element von Unvorhersehbarkeit und Vielfalt hinzu.

question mark

Was passiert mit dem animator, wenn die Methode StartState in der Klasse RunState aufgerufen wird?

Select the correct answer

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 5
some-alt