Animation fixes
This commit is contained in:
@@ -59,6 +59,8 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
|
||||
[Node] public AnimationPlayer AnimationPlayer { get; set; } = default!;
|
||||
|
||||
[Node] public AnimationTree AnimationTree { get; set; } = default!;
|
||||
|
||||
private const string IDLE_FORWARD = "idle_front_walk";
|
||||
private const string IDLE_LEFT = "idle_left_walk";
|
||||
private const string IDLE_BACK = "idle_back_walk";
|
||||
@@ -71,7 +73,13 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
EnemyLogic.Set(EnemyStatResource);
|
||||
EnemyLogic.Set(this as IEnemy);
|
||||
EnemyLogic.Set(GameRepo);
|
||||
AnimationPlayer.AnimationFinished += AnimationPlayer_AnimationFinished;
|
||||
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Start(IDLE_FORWARD);
|
||||
}
|
||||
|
||||
private void DeathAnimationPlayer_AnimationFinished(StringName animName)
|
||||
{
|
||||
GameEventDepot.OnEnemyDefeated(GlobalPosition, EnemyStatResource);
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
public void OnReady()
|
||||
@@ -89,27 +97,28 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
EnemyBinding
|
||||
.Handle((in EnemyLogic.Output.MovementComputed output) =>
|
||||
{
|
||||
if (AnimationPlayer.CurrentAnimation != "hit" && AnimationPlayer.CurrentAnimation != "attack")
|
||||
RotateEnemy(-GameRepo.PlayerGlobalTransform.Value.Basis.Z);
|
||||
RotateEnemy(-GameRepo.PlayerGlobalTransform.Value.Basis.Z);
|
||||
MoveAndSlide();
|
||||
})
|
||||
.Handle((in EnemyLogic.Output.HitByPlayer output) =>
|
||||
{
|
||||
AnimationPlayer.Stop();
|
||||
AnimationPlayer.Play("hit");
|
||||
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);
|
||||
// TODO: Make this an event to notify game that player hit someone
|
||||
if (GameRepo.PlayerData.Inventory.EquippedWeapon.Value.WeaponStats.WeaponTags.Contains(WeaponTag.SelfDamage))
|
||||
GameRepo.PlayerData.SetCurrentHP(GameRepo.PlayerData.CurrentHP.Value - 5);
|
||||
})
|
||||
.Handle((in EnemyLogic.Output.Attack _) =>
|
||||
{
|
||||
AnimationPlayer.Stop();
|
||||
AnimationPlayer.Play("attack");
|
||||
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("attack");
|
||||
})
|
||||
.Handle((in EnemyLogic.Output.Defeated output) =>
|
||||
{
|
||||
AnimationPlayer.Stop();
|
||||
AnimationPlayer.Play("defeated");
|
||||
LoadShader("res://src/vfx/shaders/PixelMelt.gdshader");
|
||||
var tweener = GetTree().CreateTween();
|
||||
tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 1.0f, 0.5f);
|
||||
tweener.TweenCallback(Callable.From(QueueFree));
|
||||
});
|
||||
|
||||
this.Provide();
|
||||
@@ -126,6 +135,14 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
PatrolTimer.WaitTime = rng.RandfRange(7.0f, 15.0f);
|
||||
}
|
||||
|
||||
private void LoadShader(string shaderPath)
|
||||
{
|
||||
var shader = GD.Load<Shader>(shaderPath);
|
||||
AnimatedSprite.Material = new ShaderMaterial();
|
||||
var shaderMaterial = (ShaderMaterial)AnimatedSprite.Material;
|
||||
shaderMaterial.Shader = shader;
|
||||
}
|
||||
|
||||
public void OnExitTree()
|
||||
{
|
||||
EnemyLogic.Stop();
|
||||
@@ -208,34 +225,29 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
|
||||
// Check if forward facing. If the dot product is -1, the enemy is facing the camera.
|
||||
if (forwardDotProduct < -rotateUpperThreshold)
|
||||
AnimationPlayer.Play("idle_front_walk");
|
||||
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("idle_front_walk");
|
||||
// Check if backward facing. If the dot product is 1, the enemy is facing the same direction as the camera.
|
||||
else if (forwardDotProduct > rotateUpperThreshold)
|
||||
AnimationPlayer.Play("idle_back_walk");
|
||||
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("idle_back_walk");
|
||||
else
|
||||
{
|
||||
// If the dot product of the perpendicular dot product is positive (up to 1), the enemy is facing to the left (since it's mirrored).
|
||||
AnimatedSprite.FlipH = leftDotProduct > 0;
|
||||
// Check is side facing. If the dot product is close to zero in the positive or negative direction, its close to the threshold for turning.
|
||||
if (Mathf.Abs(forwardDotProduct) < rotateLowerThreshold)
|
||||
AnimationPlayer.Play("idle_left_walk");
|
||||
AnimationTree.Get("parameters/playback").As<AnimationNodeStateMachinePlayback>().Travel("idle_left_walk");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHPChanged(double newHP)
|
||||
{
|
||||
if (newHP <= 0)
|
||||
{
|
||||
EnemyLogic.Input(new EnemyLogic.Input.EnemyDefeated());
|
||||
}
|
||||
}
|
||||
|
||||
private void AnimationPlayer_AnimationFinished(StringName animName)
|
||||
private void SetShaderValue(float shaderValue)
|
||||
{
|
||||
if (animName == "defeated")
|
||||
{
|
||||
GameEventDepot.OnEnemyDefeated(GlobalPosition, EnemyStatResource);
|
||||
QueueFree();
|
||||
}
|
||||
var shaderMaterial = (ShaderMaterial)AnimatedSprite.Material;
|
||||
shaderMaterial.SetShaderParameter("progress", shaderValue);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user