///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // D E R E L I C T // /// // (c) 2003..2024 using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Godot; using Godot.Sharp.Extras; namespace fsm; [GlobalClass] public partial class FSMNode : Node { [ExportCategory( "Config" )] [Export] public NodePath InitialNodePath = "Movement"; [ExportCategory( "Runtime" )] [Export] public StateNode Current = new StateNode(); [Export] public NodePath _nextNode; public virtual void Transition( NodePath nextNode ) { if( nextNode == _nextNode ) return; if( !_nextNode.IsEmpty ) { log.warn( $"{log.loc().Log}: Was going to {_nextNode} but instead going to {nextNode}" ); } _nextNode = nextNode; } public override void _Ready() { base._Ready(); this.OnReady(); Current.Name = "NOPState"; _nextNode = InitialNodePath; } public override void _PhysicsProcess( double dt ) { base._PhysicsProcess( dt ); //Do the transition if( !_nextNode.IsEmpty ) { var nextNode = GetNodeOrNull( _nextNode ); var oldNodePath = new NodePath( Current.Name ); Current.OnExit( _nextNode ); Current.ProcessMode = Node.ProcessModeEnum.Disabled; Current = nextNode; Current.OnEnter( oldNodePath ); Current.ProcessMode = Node.ProcessModeEnum.Pausable; } } }