HTX Frederikshavn & Hjørring

Det har aldrig været sjovere at være nørd

Brugerværktøjer

Webstedsværktøjer


ddu:godot:ai_fsm_2

StateMachines v2

Princip:

using Godot;
using System;
 
public partial class AIController : CharacterBody2D
{
    [Export] public float SpeedWalk = 1.5f;
    [Export] public float SpeedRun = 10f;
    private float CurrentSpeed;
 
    public Boolean IsRunning = false;
    public Boolean IsStopped = false;
 
    public CharacterBody2D Player;  // reference til vores Spiller
    public float PlayerDistance;
 
    Vector2 NextDest;   // Hvad er næste destination..gemmes her
    Vector2 MoveDirection;
 
    [Signal] public delegate void TargetReachedEventHandler();
 
 
    public override void _Ready()
    {
        // Vi opretter reference til vores Spiller
        Player = (CharacterBody2D) GetTree().GetNodesInGroup("Player")[0];
    }
 
    public override void _Process(double delta)
    {
        if (Player != null)
        {
            PlayerDistance = GlobalPosition.DistanceTo(Player.GlobalPosition);
        }
        // GD.Print("Player Distance er: " + PlayerDistance.ToString());
    }
 
    public override void _PhysicsProcess(double delta)
    {
        MoveDirection = GlobalPosition.DirectionTo(NextDest).Normalized();
 
        if ( GlobalPosition.DistanceTo(NextDest) <= 0.8f)
        {   // Sender signal om at vi har nået vores destination til abonnenter
            EmitSignal(nameof(TargetReached));
        }
 
        // Hvis AI er stopped, så sæt retning til 0.
        if (IsStopped == true) {
            MoveDirection = Vector2.Zero;
        }
 
        if (IsRunning == true)
        {
            CurrentSpeed = SpeedRun;
        }
        else {
            CurrentSpeed = SpeedWalk;
        }
 
        Velocity = MoveDirection * CurrentSpeed;
        MoveAndSlide();
    }
 
    public void MoveToPosition(Vector2 pos) 
    {
        IsStopped = false;
        NextDest = pos;
    }
}

StateMachine

using Godot;
using Godot.Collections;
using System;
 
public partial class StateMachine : Node
{
    // Den state vi starter i
    [Export] public State initialState;
    private State _currentState; // Nuværende tilstand
 
    // I denne ordbog kan jeg gemme alle mine states.
    private Dictionary<string, State> _states;
 
    public override void _Ready()
    {
        // Opretter ordbog, som jeg erklærede tidligere.
        _states = new Dictionary<string, State>();
 
        if (initialState == null) {
            GD.Print("Thomas du har glemt at sætte InitialState .. stram op.");
        }
 
        // Jeg kigger hvem jeg har som børn  :D mmkay.
        foreach (Node child in this.GetChildren()) {
            if (child is State s) {
                _states[s.Name] = s;
                s.Initialize();
            }
        }
        ChangeState(initialState.Name); // Skift til start tilstand
        GD.Print("StateMachine is ready.");
    }
 
    public void ChangeState(string stateName) {
        if (!_states.ContainsKey(stateName) || _currentState == _states[stateName] )
        {
            return; // HOP UD !!! gør ikke mere
        }
 
        if (_currentState != null)
            _currentState.Exit();   // Vi hopper af nuværende tilstand (oprydning)
 
        _currentState = _states[stateName]; // sætter nuværende tilstand til nye tilstand.
        _currentState.Enter();  // Initialisere
 
        GD.Print("Changed state to: " + stateName);
    }
 
    override public void _Process(double delta) {
        _currentState.Update(delta);
    }
 
    public override void _PhysicsProcess(double delta)
    {
        _currentState.PhysicsUpdate(delta);
    }
 
    public void OnTargetReached() {
        if (_currentState != null) {
            _currentState.NavigationComplete();
        }
    }
 
}

PatrolState

using Godot;
using System;
 
public partial class PatrolState : State
{
    [Export] public Node2D[] waypoints;
    [Export] public float ChaseRange = 120f;
 
    private int _currentWaypointIndex = 0;
 
    override public void Enter() {
        base.Enter();   // Kalder den klasse State som vi nedarver fra.
        Controller.MoveToPosition( waypoints[_currentWaypointIndex].GlobalPosition );
    }
 
    override public void Update(double delta) {
        if (Controller.PlayerDistance < ChaseRange) {
            fsm.ChangeState("Chase");
        }
    }
 
    override public void NavigationComplete() {
        _currentWaypointIndex++;
        // Hvis vi er nået til sidste waypoint, så sæt næste waypoint til index 0.
        if (_currentWaypointIndex >= waypoints.Length) {
            _currentWaypointIndex = 0;
        }
 
        Controller.MoveToPosition( waypoints[_currentWaypointIndex].GlobalPosition );
    }
}
 
 
ddu/godot/ai_fsm_2.txt · Sidst ændret: af 127.0.0.1