Laufzustand
csharp991234567891011121314public 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.
Virtuell bedeutet, dass abgeleitete Klassen diese Methode überschreiben können, wenn sie zusätzliche Aktionen ausführen müssen, wenn ein Zustand endet.
Warum diese Änderungen vorgenommen wurden
Die Änderungen führen die Variable isStateFinished
ein, um den Abschluss eines Zustands zu verfolgen, und die FinishState
-Methode, um die Signalisierung des Zustandsabschlusses zu standardisieren, sodass abgeleitete Klassen benutzerdefinierte Logik beim Zustandsabschluss hinzufügen können.
Laufzustand
csharp99123456789101112131415161718192021222324252627282930313233343536public 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(){
Schauen wir uns die RunState
-Klasse an, die von der State
-Klasse erbt. Diese Klasse ist verantwortlich für das Handling des Laufverhaltens unseres Feindes. Wir konzentrieren uns auf die Ergänzungen und Änderungen, die an dieser Klasse vorgenommen wurden.
Konstruktor:
public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
;
Dieser Konstruktor initialisiert den RunState
mit den notwendigen Komponenten: einem Rigidbody2D
für die Bewegung, einem Animator
für die Animationen, einem Transform
, um den Spieler zu verfolgen, und einer speed
, um festzulegen, wie schnell der Feind läuft;
StartState-Methode:
public override void StartState()
;
Diese Methode setzt isStateFinished
auf false
und löst die Laufanimation aus, indem der "run"-boolesche Parameter im Animator auf true
gesetzt wird.
UpdateState Methode:
public override void UpdateState(float DeltaTime)
;
Diese Methode aktualisiert die Position und Ausrichtung des Feindes basierend auf der Position des Spielers;
Sie passt die Skalierung des Feindes an, um dem Spieler zugewandt zu sein, berechnet die Geschwindigkeit basierend auf der Geschwindigkeit und wendet diese Geschwindigkeit auf das Rigidbody2D
an.
EndState Methode:
public override void EndState()
Diese Methode stoppt die Laufanimation, indem sie den "run"-booleschen Parameter im Animator auf false
setzt.
Funktionsweise für unseren Feind
Bewegung und Animation: Durch die Verwendung von
Rigidbody2D
undAnimator
stellt derRunState
sicher, dass sich der Feind reibungslos bewegen kann und entsprechende Animationen hat. Dies macht das Verhalten visuell und physisch realistisch;Verfolgung der Spielerposition: Der
player
-Transform ermöglicht es dem Feind, sich immer in Richtung des Spielers zu bewegen, was für Verfolgungs- oder Laufverhalten unerlässlich ist;Richtungssteuerung: Die Anpassung der
scale.x
basierend auf der Position des Spielers stellt sicher, dass der Feind dem Spieler korrekt zugewandt ist, während er läuft, was zur Realismus beiträgt;Dynamische Zustandsaktualisierungen: Die
UpdateState
-Methode wird in jedem Frame aufgerufen, um kontinuierlich die Bewegung und Richtung des Feindes basierend auf der Position des Spielers anzupassen, wodurch der Feind reaktionsschnell und dynamisch wird.
Feindinitialisierung
csharp9912345678910111213141516171819202122232425private 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
Zustandsinitialisierung:
Die Variablen idle
und runState
werden mit ihren jeweiligen Zuständen initialisiert. Die Variable idle
ist eine Instanz von IdleState
mit dem Animator, während runState
eine Instanz von RunState
ist, die ein Rigidbody2D
, Animator
, Transform
für den Spieler und einen Geschwindigkeitswert enthält.
StateManager-Initialisierung:
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 überprüft, ob der Spieler weiter entfernt ist alsThresholdDistance
;toIdleTransition:
toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100));
Dieser Übergang überprüft, ob der aktuelle Zustand abgeschlossen ist. Wenn ja, wechselt er mit 100% Wahrscheinlichkeit in denidle
-Zustand.finishRunning:
finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100));
Dieser Übergang überprüft, ob der Spieler näher ist alsThresholdDistance
. Wenn ja, wechselt er mit 100% Wahrscheinlichkeit in denidle
-Zustand.
Übergänge zum StateManager hinzufügen:
csharp9123stateManager.AddStateTransition(idle, FarAwayTransition);stateManager.AddStateTransition(dashState, toIdleTransition);stateManager.AddStateTransition(runState, finishRunning);
Diese Zeilen fügen die definierten Übergänge zum stateManager
hinzu.
Warum wir es so gemacht haben
Dynamische Zustandsänderungen:
Die Übergänge ermöglichen es dem Feind, sein Verhalten dynamisch basierend auf der Position des Spielers und dem Abschlussstatus des aktuellen Zustands zu ändern, wodurch der Feind innerhalb der Spielumgebung reaktionsfähiger und interaktiver wird.
Bedingte Übergänge:
Der Einsatz von Bedingungen (wie das Überprüfen der Entfernung oder des Zustandsabschlusses) stellt sicher, dass Zustandsübergänge logisch und angemessen erfolgen, was die Spielrealität verbessert.
Wahrscheinlichkeitsbasierte Übergänge:
Die Verwendung von StatePourcentage
ermöglicht wahrscheinlichkeitsbasierte Übergänge, die dem Verhalten des Feindes ein Element der Unvorhersehbarkeit und Vielfalt hinzufügen.
Danke für Ihr Feedback!
Fragen Sie AI
Fragen Sie alles oder probieren Sie eine der vorgeschlagenen Fragen, um unser Gespräch zu beginnen