Rework enemy behavior (still in progress but shouldn't crash)

This commit is contained in:
2025-10-20 19:24:50 -07:00
parent 20b659681a
commit 44fd8c82b0
135 changed files with 2165 additions and 2415 deletions

View File

@@ -5,7 +5,7 @@ using System.Linq;
namespace Zennysoft.Game.Ma;
[Meta(typeof(IAutoNode))]
public partial class EnemyModelView2D : Node3D, IEnemyModelView
public partial class EnemyModelView2D : EnemyModelView, IEnemyModelView
{
private readonly string _idleName = "Idle";
private readonly string _walkingName = "Walking";
@@ -19,7 +19,7 @@ public partial class EnemyModelView2D : Node3D, IEnemyModelView
[Node] public AnimatedSprite2D AnimatedSprite { get; set; } = default!;
[Node] public IHitbox Hitbox { get; set; } = default!;
[Node] public Area3D Hitbox { get; set; } = default!;
[Node] public AnimationPlayer AnimationPlayer { get; set; } = default!;
@@ -37,9 +37,12 @@ public partial class EnemyModelView2D : Node3D, IEnemyModelView
public void OnReady()
{
_stateMachine = (AnimationNodeStateMachinePlayback)AnimationTree.Get("parameters/playback");
_stateMachine = (AnimationNodeStateMachinePlayback)AnimationTree.Get("parameters/playback");
Hitbox.BodyEntered += Hitbox_BodyEntered;
}
private void Hitbox_BodyEntered(Node3D body) => EmitSignal(SignalName.HitPlayer);
public void SetCurrentDirection(Basis enemyBasis, Vector3 cameraDirection) => _enemyDirection = GetEnemyDirection(enemyBasis, cameraDirection, _upperThreshold, _lowerThreshold);
public void PlayPrimaryAttackAnimation() => _stateMachine.Travel(_primaryAttackName);
@@ -52,115 +55,116 @@ public partial class EnemyModelView2D : Node3D, IEnemyModelView
public void PlayWalkAnimation() => _stateMachine.Travel(_walkingName);
public void PlayActivateAnimation() => _stateMachine.Travel(_activateName);
public void PlayActivateAnimation()
{
}
public void PlayHitAnimation()
{
LoadShader("res://src/vfx/shaders/DamageHit.gdshader");
var tweener = GetTree().CreateTween();
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
LoadShader("res://src/vfx/shaders/DamageHit.gdshader");
var tweener = GetTree().CreateTween();
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 1.0f);
}
public void PlayDeathAnimation()
{
LoadShader("res://src/vfx/shaders/PixelMelt.gdshader");
var tweener = GetTree().CreateTween();
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 0.8f);
tweener.TweenCallback(Callable.From(QueueFree));
LoadShader("res://src/vfx/shaders/PixelMelt.gdshader");
var tweener = GetTree().CreateTween();
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 0.8f);
}
private EnemyDirection GetEnemyDirection(
Basis enemyBasis,
Vector3 cameraDirection,
float rotateUpperThreshold,
float rotateLowerThreshold)
Basis enemyBasis,
Vector3 cameraDirection,
float rotateUpperThreshold,
float rotateLowerThreshold)
{
var enemyForwardDirection = enemyBasis.Z;
var enemyLeftDirection = enemyBasis.X;
var enemyForwardDirection = enemyBasis.Z;
var enemyLeftDirection = enemyBasis.X;
var leftDotProduct = enemyLeftDirection.Dot(cameraDirection);
var forwardDotProduct = enemyForwardDirection.Dot(cameraDirection);
var leftDotProduct = enemyLeftDirection.Dot(cameraDirection);
var forwardDotProduct = enemyForwardDirection.Dot(cameraDirection);
// Check if forward facing. If the dot product is -1, the enemy is facing the camera.
if (forwardDotProduct < _lowerThreshold)
{
SetForward();
return EnemyDirection.Forward;
}
// Check if forward facing. If the dot product is -1, the enemy is facing the camera.
if (forwardDotProduct < _lowerThreshold)
{
SetForward();
return EnemyDirection.Forward;
}
// Check if backward facing. If the dot product is 1, the enemy is facing the same direction as the camera.
else if (forwardDotProduct > rotateUpperThreshold)
{
SetBack();
return EnemyDirection.Backward;
}
else
{
// If the dot product of the perpendicular direction is positive (up to 1), the enemy is facing to the left (since it's mirrored).
if (leftDotProduct < _lowerThreshold)
{
SetRight();
return EnemyDirection.Left;
}
// Check if backward facing. If the dot product is 1, the enemy is facing the same direction as the camera.
else if (forwardDotProduct > rotateUpperThreshold)
{
SetBack();
return EnemyDirection.Backward;
}
else
{
// If the dot product of the perpendicular direction is positive (up to 1), the enemy is facing to the left (since it's mirrored).
if (leftDotProduct < _lowerThreshold)
{
SetRight();
return EnemyDirection.Left;
}
// Check if side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
if (leftDotProduct > rotateUpperThreshold)
{
SetLeft();
return EnemyDirection.Right;
}
}
// Check if side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
if (leftDotProduct > rotateUpperThreshold)
{
SetLeft();
return EnemyDirection.Right;
}
}
return _enemyDirection;
return _enemyDirection;
}
private void LoadShader(string shaderPath)
{
var shader = GD.Load<Shader>(shaderPath);
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
foreach (var sprite in sprites)
{
sprite.Material = new ShaderMaterial();
var shaderMaterial = (ShaderMaterial)sprite.Material;
shaderMaterial.Shader = shader;
}
var shader = GD.Load<Shader>(shaderPath);
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
foreach (var sprite in sprites)
{
sprite.Material = new ShaderMaterial();
var shaderMaterial = (ShaderMaterial)sprite.Material;
shaderMaterial.Shader = shader;
}
}
private void SetShaderValue(float shaderValue)
{
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
foreach (var sprite in sprites)
{
var shaderMaterial = (ShaderMaterial)sprite.Material;
shaderMaterial.SetShaderParameter("progress", shaderValue);
}
var sprites = FindChildren("*", "AnimatedSprite2D", true).Cast<AnimatedSprite2D>();
foreach (var sprite in sprites)
{
var shaderMaterial = (ShaderMaterial)sprite.Material;
shaderMaterial.SetShaderParameter("progress", shaderValue);
}
}
private void SetForward()
{
_enemyDirection = EnemyDirection.Forward;
_enemyDirection = EnemyDirection.Forward;
}
private void SetLeft()
{
_enemyDirection = EnemyDirection.Left;
_enemyDirection = EnemyDirection.Left;
}
private void SetRight()
{
_enemyDirection = EnemyDirection.Right;
_enemyDirection = EnemyDirection.Right;
}
private void SetBack()
{
_enemyDirection = EnemyDirection.Backward;
_enemyDirection = EnemyDirection.Backward;
}
private enum EnemyDirection
{
Left,
Right,
Forward,
Backward
Left,
Right,
Forward,
Backward
}
}