Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lernen Zustandsübergang | 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
Zustandsübergang

public class Transition
{
    Func<bool> condition;
    List<StatePourcentage> availableStates;

    public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage)
    {
        this.condition = condition;
        availableStates = new List<StatePourcentage>();
        for (int i = 0; i < statePourcentage.Length; i++)
        {
            availableStates.Add(statePourcentage[i]);
        }
    }

    public State GetState()
    {
        float percentage = UnityEngine.Random.Range(0, 100);
        float currentPercentage = 0;
        foreach (var statePer in availableStates)
        {
            currentPercentage += statePer.percentage;
            if (percentage <= currentPercentage)
            {
                return statePer.state;
            }
        }
        return null;
    }

    public bool IsConditionMet()
    {
        return condition();
    }
}
public class StatePourcentage
{
    public State state;
    public float percentage;

    public StatePourcentage(State state, float percentage)
    {
        this.state = state;
        this.percentage = percentage;
    }
}

In diesen Beispielen sehen wir eine Transition-Klasse und eine StatePourcentage-Klasse. Diese Klassen arbeiten zusammen, um Übergänge zwischen verschiedenen Zuständen basierend auf bestimmten Bedingungen und Wahrscheinlichkeiten zu steuern. Im Folgenden wird erläutert, was dieser Code in einfachen Worten macht:

Erklärung

StatePourcentage-Klasse

Klassendefinition: Die Zeile public class StatePourcentage definiert eine Klasse namens StatePourcentage. Diese Klasse speichert Informationen über einen Zustand und die prozentuale Wahrscheinlichkeit, zu diesem Zustand zu wechseln.

Mitgliedsvariablen:

public State state; enthält eine Referenz auf einen Zustand. public float percentage; enthält die prozentuale Wahrscheinlichkeit für den Übergang zu diesem Zustand.

Konstruktor:

public StatePourcentage(State state, float percentage) ist ein Konstruktor. Er nimmt einen State und einen float als Parameter und weist sie den Mitgliedsvariablen zu.

Transition-Klasse

Klassendefinition: Die Zeile public class Transition definiert eine Klasse namens Transition. Diese Klasse verwaltet die Logik für Zustandsübergänge basierend auf einer Bedingung und Wahrscheinlichkeiten.

Mitgliedsvariablen: Func<bool> condition; ist ein Delegat, der eine Bedingungsfunktion enthält. Diese Funktion gibt einen booleschen Wert zurück, der angibt, ob die Übergangsbedingung erfüllt ist.

List<StatePourcentage> availableStates; ist eine Liste, die mehrere StatePourcentage-Objekte enthält, welche mögliche Zielzustände und deren jeweilige Wahrscheinlichkeiten repräsentieren.

Konstruktor: public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage) ist ein Konstruktor. Er nimmt eine Bedingungsfunktion und ein Array von StatePourcentage-Objekten als Parameter entgegen. Er initialisiert die Mitgliedsvariable condition mit der bereitgestellten Bedingungsfunktion und erstellt eine neue Liste für availableStates, in die jedes StatePourcentage-Objekt aus dem Array hinzugefügt wird.

GetState-Methode: public State GetState() ist eine Methode, die bestimmt, zu welchem Zustand gewechselt werden soll, basierend auf einer zufälligen Auswahl und den angegebenen Wahrscheinlichkeiten. Sie generiert eine Zufallszahl zwischen 0 und 100 und durchläuft die verfügbaren Zustände, summiert deren Wahrscheinlichkeiten und wählt den Zustand aus, der zur Zufallszahl passt.

IsConditionMet-Methode: public bool IsConditionMet() ist eine Methode, die prüft, ob die Übergangsbedingung erfüllt ist, indem sie die Bedingungsfunktion aufruft. Sie gibt das Ergebnis der Bedingungsfunktion zurück.

Funktionsweise für unseren Gegner

Übergangseinrichtung: Es werden Übergänge zwischen Zuständen definiert, wobei die Bedingungen festgelegt werden, unter denen diese Übergänge stattfinden, sowie die Wahrscheinlichkeiten für den Wechsel in jeden Zustand.

Bestimmung des nächsten Zustands: Wenn ein Übergang ausgelöst wird, wählt die Methode GetState() den nächsten Zustand zufällig basierend auf den definierten Wahrscheinlichkeiten aus. Dies verleiht dem Verhalten des Gegners ein Element der Unvorhersehbarkeit und macht ihn dynamischer und herausfordernder.

Überprüfung der Bedingungen: Die Methode IsConditionMet() wird verwendet, um zu prüfen, ob die Bedingungen für einen Übergang erfüllt sind. Ist die Bedingung wahr, kann der Übergang erfolgen und die Methode GetState() bestimmt den nächsten Zustand.

Zustandsmanager

public class StateManager
{
    State currentState;
    Dictionary<State, List<Transition>> stateTransitions;

    public StateManager(State startingState)
    {
        currentState = startingState;
        currentState.StartState();
        stateTransitions = new Dictionary<State, List<Transition>>();
    }

    public void AddStateTransition(State state, Transition transition)
    {
        if (!stateTransitions.ContainsKey(state))
        {
            stateTransitions.Add(state, new List<Transition>());
        }
        stateTransitions[state].Add(transition);
    }

    public void ChangeState(State newState)
    {
        currentState.EndState();
        currentState = newState;
        currentState.StartState();
    }

    public void UpdateStates(float deltaTime)
    {
        currentState.UpdateState(deltaTime);
        List<Transition> stateTransitionsList = stateTransitions[currentState];
        if (stateTransitionsList == null || stateTransitionsList.Count == 0) return;
        foreach (var transition in stateTransitionsList)
        {
            if (transition.IsConditionMet())
            {
                ChangeState(transition.GetState());
                break;
            }
        }
    }
}

Änderungen und Ergänzungen

State Transitions Dictionary: Dictionary<State, List<Transition>> stateTransitions; ist ein Dictionary, das Listen von Übergängen für jeden Zustand enthält. Jeder Zustand ist mit einer Liste möglicher Übergänge verknüpft, die beim Aktualisieren des Zustands überprüft werden können.

Konstruktor: stateTransitions = new Dictionary<State, List<Transition>>(); initialisiert das stateTransitions-Dictionary im Konstruktor und stellt sicher, dass es bereit ist, Übergänge für verschiedene Zustände zu speichern.

AddStateTransition-Methode: public void AddStateTransition(State state, Transition transition) ist eine Methode, die einen Übergang zur Liste der Übergänge für einen bestimmten Zustand hinzufügt. Falls der Zustand noch keinen Eintrag im Dictionary hat, wird ein neuer Eintrag mit einer leeren Übergangsliste erstellt. Der Übergang wird dann der Liste der Übergänge für den angegebenen Zustand hinzugefügt.

UpdateStates-Methode: Die UpdateStates-Methode wurde so angepasst, dass sie zunächst die Übergänge überprüft, indem sie nach der Aktualisierung mit currentState.UpdateState(deltaTime); die Liste der Übergänge für den aktuellen Zustand abruft. Anschließend wird jeder Übergang in der Liste daraufhin überprüft, ob die Übergangsbedingung mit transition.IsConditionMet() erfüllt ist. Wenn eine Übergangsbedingung erfüllt ist, wird der Zustand mit ChangeState(transition.GetState()); gewechselt und die Schleife abgebrochen, um mehrere Zustandswechsel in einem Update zu verhindern.

Gründe für diese Änderungen

Die Ergänzung des stateTransitions-Dictionaries und der AddStateTransition-Methode ermöglicht es dem StateManager, mehrere potenzielle Übergänge für jeden Zustand zu verwalten, was die Flexibilität und Komplexität des Zustandsautomaten erhöht. Durch das dynamische Überprüfen von Übergängen innerhalb der UpdateStates-Methode ermöglicht der StateManager dem Gegner, in Echtzeit auf verschiedene Ereignisse und Bedingungen zu reagieren. Die aktualisierte Methode stellt sicher, dass zunächst der aktuelle Zustand aktualisiert und anschließend mögliche Übergänge überprüft werden, wodurch eine korrekte Ausführung der Zustandslogik vor der Entscheidungsfindung für einen Übergang gewährleistet wird.

Durch die Umsetzung dieser Änderungen wird der StateManager besser in der Lage sein, komplexe und vielfältige Verhaltensweisen zu steuern, wodurch die Aktionen des Gegners dynamischer und reaktiver auf die Spielumgebung werden.

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 4

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
Zustandsübergang

public class Transition
{
    Func<bool> condition;
    List<StatePourcentage> availableStates;

    public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage)
    {
        this.condition = condition;
        availableStates = new List<StatePourcentage>();
        for (int i = 0; i < statePourcentage.Length; i++)
        {
            availableStates.Add(statePourcentage[i]);
        }
    }

    public State GetState()
    {
        float percentage = UnityEngine.Random.Range(0, 100);
        float currentPercentage = 0;
        foreach (var statePer in availableStates)
        {
            currentPercentage += statePer.percentage;
            if (percentage <= currentPercentage)
            {
                return statePer.state;
            }
        }
        return null;
    }

    public bool IsConditionMet()
    {
        return condition();
    }
}
public class StatePourcentage
{
    public State state;
    public float percentage;

    public StatePourcentage(State state, float percentage)
    {
        this.state = state;
        this.percentage = percentage;
    }
}

In diesen Beispielen sehen wir eine Transition-Klasse und eine StatePourcentage-Klasse. Diese Klassen arbeiten zusammen, um Übergänge zwischen verschiedenen Zuständen basierend auf bestimmten Bedingungen und Wahrscheinlichkeiten zu steuern. Im Folgenden wird erläutert, was dieser Code in einfachen Worten macht:

Erklärung

StatePourcentage-Klasse

Klassendefinition: Die Zeile public class StatePourcentage definiert eine Klasse namens StatePourcentage. Diese Klasse speichert Informationen über einen Zustand und die prozentuale Wahrscheinlichkeit, zu diesem Zustand zu wechseln.

Mitgliedsvariablen:

public State state; enthält eine Referenz auf einen Zustand. public float percentage; enthält die prozentuale Wahrscheinlichkeit für den Übergang zu diesem Zustand.

Konstruktor:

public StatePourcentage(State state, float percentage) ist ein Konstruktor. Er nimmt einen State und einen float als Parameter und weist sie den Mitgliedsvariablen zu.

Transition-Klasse

Klassendefinition: Die Zeile public class Transition definiert eine Klasse namens Transition. Diese Klasse verwaltet die Logik für Zustandsübergänge basierend auf einer Bedingung und Wahrscheinlichkeiten.

Mitgliedsvariablen: Func<bool> condition; ist ein Delegat, der eine Bedingungsfunktion enthält. Diese Funktion gibt einen booleschen Wert zurück, der angibt, ob die Übergangsbedingung erfüllt ist.

List<StatePourcentage> availableStates; ist eine Liste, die mehrere StatePourcentage-Objekte enthält, welche mögliche Zielzustände und deren jeweilige Wahrscheinlichkeiten repräsentieren.

Konstruktor: public Transition(Func<bool> condition, params StatePourcentage[] statePourcentage) ist ein Konstruktor. Er nimmt eine Bedingungsfunktion und ein Array von StatePourcentage-Objekten als Parameter entgegen. Er initialisiert die Mitgliedsvariable condition mit der bereitgestellten Bedingungsfunktion und erstellt eine neue Liste für availableStates, in die jedes StatePourcentage-Objekt aus dem Array hinzugefügt wird.

GetState-Methode: public State GetState() ist eine Methode, die bestimmt, zu welchem Zustand gewechselt werden soll, basierend auf einer zufälligen Auswahl und den angegebenen Wahrscheinlichkeiten. Sie generiert eine Zufallszahl zwischen 0 und 100 und durchläuft die verfügbaren Zustände, summiert deren Wahrscheinlichkeiten und wählt den Zustand aus, der zur Zufallszahl passt.

IsConditionMet-Methode: public bool IsConditionMet() ist eine Methode, die prüft, ob die Übergangsbedingung erfüllt ist, indem sie die Bedingungsfunktion aufruft. Sie gibt das Ergebnis der Bedingungsfunktion zurück.

Funktionsweise für unseren Gegner

Übergangseinrichtung: Es werden Übergänge zwischen Zuständen definiert, wobei die Bedingungen festgelegt werden, unter denen diese Übergänge stattfinden, sowie die Wahrscheinlichkeiten für den Wechsel in jeden Zustand.

Bestimmung des nächsten Zustands: Wenn ein Übergang ausgelöst wird, wählt die Methode GetState() den nächsten Zustand zufällig basierend auf den definierten Wahrscheinlichkeiten aus. Dies verleiht dem Verhalten des Gegners ein Element der Unvorhersehbarkeit und macht ihn dynamischer und herausfordernder.

Überprüfung der Bedingungen: Die Methode IsConditionMet() wird verwendet, um zu prüfen, ob die Bedingungen für einen Übergang erfüllt sind. Ist die Bedingung wahr, kann der Übergang erfolgen und die Methode GetState() bestimmt den nächsten Zustand.

Zustandsmanager

public class StateManager
{
    State currentState;
    Dictionary<State, List<Transition>> stateTransitions;

    public StateManager(State startingState)
    {
        currentState = startingState;
        currentState.StartState();
        stateTransitions = new Dictionary<State, List<Transition>>();
    }

    public void AddStateTransition(State state, Transition transition)
    {
        if (!stateTransitions.ContainsKey(state))
        {
            stateTransitions.Add(state, new List<Transition>());
        }
        stateTransitions[state].Add(transition);
    }

    public void ChangeState(State newState)
    {
        currentState.EndState();
        currentState = newState;
        currentState.StartState();
    }

    public void UpdateStates(float deltaTime)
    {
        currentState.UpdateState(deltaTime);
        List<Transition> stateTransitionsList = stateTransitions[currentState];
        if (stateTransitionsList == null || stateTransitionsList.Count == 0) return;
        foreach (var transition in stateTransitionsList)
        {
            if (transition.IsConditionMet())
            {
                ChangeState(transition.GetState());
                break;
            }
        }
    }
}

Änderungen und Ergänzungen

State Transitions Dictionary: Dictionary<State, List<Transition>> stateTransitions; ist ein Dictionary, das Listen von Übergängen für jeden Zustand enthält. Jeder Zustand ist mit einer Liste möglicher Übergänge verknüpft, die beim Aktualisieren des Zustands überprüft werden können.

Konstruktor: stateTransitions = new Dictionary<State, List<Transition>>(); initialisiert das stateTransitions-Dictionary im Konstruktor und stellt sicher, dass es bereit ist, Übergänge für verschiedene Zustände zu speichern.

AddStateTransition-Methode: public void AddStateTransition(State state, Transition transition) ist eine Methode, die einen Übergang zur Liste der Übergänge für einen bestimmten Zustand hinzufügt. Falls der Zustand noch keinen Eintrag im Dictionary hat, wird ein neuer Eintrag mit einer leeren Übergangsliste erstellt. Der Übergang wird dann der Liste der Übergänge für den angegebenen Zustand hinzugefügt.

UpdateStates-Methode: Die UpdateStates-Methode wurde so angepasst, dass sie zunächst die Übergänge überprüft, indem sie nach der Aktualisierung mit currentState.UpdateState(deltaTime); die Liste der Übergänge für den aktuellen Zustand abruft. Anschließend wird jeder Übergang in der Liste daraufhin überprüft, ob die Übergangsbedingung mit transition.IsConditionMet() erfüllt ist. Wenn eine Übergangsbedingung erfüllt ist, wird der Zustand mit ChangeState(transition.GetState()); gewechselt und die Schleife abgebrochen, um mehrere Zustandswechsel in einem Update zu verhindern.

Gründe für diese Änderungen

Die Ergänzung des stateTransitions-Dictionaries und der AddStateTransition-Methode ermöglicht es dem StateManager, mehrere potenzielle Übergänge für jeden Zustand zu verwalten, was die Flexibilität und Komplexität des Zustandsautomaten erhöht. Durch das dynamische Überprüfen von Übergängen innerhalb der UpdateStates-Methode ermöglicht der StateManager dem Gegner, in Echtzeit auf verschiedene Ereignisse und Bedingungen zu reagieren. Die aktualisierte Methode stellt sicher, dass zunächst der aktuelle Zustand aktualisiert und anschließend mögliche Übergänge überprüft werden, wodurch eine korrekte Ausführung der Zustandslogik vor der Entscheidungsfindung für einen Übergang gewährleistet wird.

Durch die Umsetzung dieser Änderungen wird der StateManager besser in der Lage sein, komplexe und vielfältige Verhaltensweisen zu steuern, wodurch die Aktionen des Gegners dynamischer und reaktiver auf die Spielumgebung werden.

War alles klar?

Wie können wir es verbessern?

Danke für Ihr Feedback!

Abschnitt 3. Kapitel 4
some-alt