Skip to content

Commit

Permalink
#16 Udemy 2.5D RPG Enemies patrolling
Browse files Browse the repository at this point in the history
  • Loading branch information
John Ludlow committed Sep 6, 2024
1 parent 3b2a2be commit 6c26b21
Show file tree
Hide file tree
Showing 7 changed files with 234 additions and 32 deletions.
28 changes: 14 additions & 14 deletions Udemy25dRpg/Resources/Tiles.tres

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ public abstract partial class CharacterBase : CharacterBody3D
[Export, ExportGroup("Required Nodes")]
public AnimatedSprite3D AnimatedSprite3DNode { get; protected set; }

[Export, ExportGroup("AI Nodes")]
public Path3D PathNode { get; private set; }

[Export, ExportGroup("AI Nodes")]
public NavigationAgent3D NavigationAgentNode { get; private set; }

public Vector2 Direction { get; protected set; } = Vector2.Zero;

public void FlipSprite()
Expand Down
20 changes: 16 additions & 4 deletions Udemy25dRpg/Scenes/Characters/Enemy/Enemy.tscn
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[gd_scene load_steps=105 format=3 uid="uid://26cy6bbsdt37"]
[gd_scene load_steps=107 format=3 uid="uid://26cy6bbsdt37"]

[ext_resource type="Texture2D" uid="uid://ckonrd67f8enh" path="res://Assets/Sprites/Characters/Enemy Knight/Attack/0_Demons_of_Darkness_Slashing_000.png" id="1_gty22"]
[ext_resource type="Texture2D" uid="uid://cjdjjbuattvtu" path="res://Assets/Sprites/Characters/Enemy Knight/Idle/0_Demons_of_Darkness_Idle_000.png" id="1_le6bp"]
Expand Down Expand Up @@ -102,6 +102,8 @@
[ext_resource type="Texture2D" uid="uid://b4pv0ny4xgeme" path="res://Assets/Sprites/Characters/Enemy Knight/TakeHit/0_Demons_of_Darkness_Hurt_011.png" id="99_5kr26"]
[ext_resource type="PackedScene" uid="uid://chsjgdc42gn10" path="res://Scenes/Characters/StateMachine.tscn" id="101_svyoj"]
[ext_resource type="Script" path="res://Scenes/Characters/Enemy/EnemyIdleState.cs" id="102_d6q6i"]
[ext_resource type="Script" path="res://Scenes/Characters/Enemy/EnemyReturnState.cs" id="103_k2nhi"]
[ext_resource type="Script" path="res://Scenes/Characters/Enemy/EnemyPatrolState.cs" id="104_0iq21"]

[sub_resource type="SpriteFrames" id="SpriteFrames_nl2d3"]
animations = [{
Expand Down Expand Up @@ -432,27 +434,37 @@ animations = [{
radius = 0.549619
height = 1.29953

[node name="Enemy" type="CharacterBody3D" node_paths=PackedStringArray("StateMachineNode", "AnimatedSprite3DNode")]
[node name="Enemy" type="CharacterBody3D" node_paths=PackedStringArray("StateMachineNode", "AnimatedSprite3DNode", "NavigationAgentNode")]
collision_layer = 4
collision_mask = 7
floor_max_angle = 1.55334
floor_snap_length = 100.0
script = ExtResource("1_tph2b")
StateMachineNode = NodePath("StateMachine")
AnimatedSprite3DNode = NodePath("AnimatedSprite3D")
NavigationAgentNode = NodePath("NavigationAgent3D")

[node name="AnimatedSprite3D" type="AnimatedSprite3D" parent="."]
pixel_size = 0.0025
sprite_frames = SubResource("SpriteFrames_nl2d3")
animation = &"Idle"
animation = &"Move"

[node name="StateMachine" parent="." node_paths=PackedStringArray("CurrentState", "PossibleStates") instance=ExtResource("101_svyoj")]
CurrentState = NodePath("IdleState")
PossibleStates = [NodePath("IdleState"), NodePath(""), NodePath("")]
PossibleStates = [NodePath("IdleState"), NodePath("ReturnState"), NodePath("PatrolState")]

[node name="IdleState" type="Node" parent="StateMachine"]
script = ExtResource("102_d6q6i")

[node name="ReturnState" type="Node" parent="StateMachine"]
script = ExtResource("103_k2nhi")

[node name="PatrolState" type="Node" parent="StateMachine"]
script = ExtResource("104_0iq21")

[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0016498, -0.0394009, 0.0142541)
shape = SubResource("CapsuleShape3D_vahjm")

[node name="NavigationAgent3D" type="NavigationAgent3D" parent="."]
debug_enabled = true
13 changes: 10 additions & 3 deletions Udemy25dRpg/Scenes/Characters/Enemy/EnemyIdleState.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using Godot;
using System;

namespace Udemy25dRpg.Scenes.Characters.Enemy;

public partial class EnemyIdleState : StateMachineStateBase
Expand All @@ -9,4 +6,14 @@ protected override void EnterState()
{
_characterNode.AnimatedSprite3DNode.Play(nameof(Enemy.EnemyAnimations.Idle));
}

public override void _PhysicsProcess(double delta)
{
base._PhysicsProcess(delta);

if (_characterNode.NavigationAgentNode.IsNodeReady())
{
_characterNode.StateMachineNode.SwitchState<EnemyReturnState>();
}
}
}
31 changes: 31 additions & 0 deletions Udemy25dRpg/Scenes/Characters/Enemy/EnemyPatrolState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace Udemy25dRpg.Scenes.Characters.Enemy;

public partial class EnemyPatrolState : StateMachineStateBase
{
private int _pathNodeIndex = 0;

protected override void EnterState()
{
_characterNode.AnimatedSprite3DNode.Play(nameof(Enemy.EnemyAnimations.Move));
}

public override void _PhysicsProcess(double delta)
{
base._PhysicsProcess(delta);

if (_characterNode.NavigationAgentNode.IsNodeReady() && _characterNode.NavigationAgentNode.IsNavigationFinished())
{
if (_pathNodeIndex >= _characterNode.PathNode.Curve.PointCount)
{
_pathNodeIndex = 0;
}

_characterNode.NavigationAgentNode.TargetPosition =
_characterNode.PathNode.Curve.GetPointPosition(_pathNodeIndex++) +
_characterNode.PathNode.GlobalPosition;
}

_characterNode.Velocity = _characterNode.GlobalPosition.DirectionTo(_characterNode.NavigationAgentNode.TargetPosition);
_characterNode.MoveAndSlide();
}
}
35 changes: 35 additions & 0 deletions Udemy25dRpg/Scenes/Characters/Enemy/EnemyReturnState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using Godot;

namespace Udemy25dRpg.Scenes.Characters.Enemy;

public partial class EnemyReturnState : StateMachineStateBase
{
private Vector3 _destination;

public override void _Ready()
{
base._Ready();

_destination =
_characterNode.PathNode.Curve.GetPointPosition(0) +
_characterNode.PathNode.GlobalPosition;
}

protected override void EnterState()
{
_characterNode.AnimatedSprite3DNode.Play(nameof(Enemy.EnemyAnimations.Move));
_characterNode.NavigationAgentNode.TargetPosition = _destination;
}

public override void _PhysicsProcess(double delta)
{
if (_characterNode.NavigationAgentNode.IsNavigationFinished())
{
_characterNode.StateMachineNode.SwitchState<EnemyPatrolState>();
return;
}

_characterNode.Velocity = _characterNode.GlobalPosition.DirectionTo(_destination);
_characterNode.MoveAndSlide();
}
}
Loading

0 comments on commit 6c26b21

Please sign in to comment.