Rough collision avoidance implementation using pre-generated floors (just floor 01)
This commit is contained in:
@@ -2,6 +2,9 @@ using Chickensoft.AutoInject;
|
||||
using Chickensoft.Collections;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
@@ -22,7 +25,7 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
|
||||
[Dependency] IGameEventDepot GameEventDepot => this.DependOn<IGameEventDepot>();
|
||||
|
||||
[Dependency] protected IPlayer Player => this.DependOn<IPlayer>();
|
||||
[Dependency] protected IPlayer Player => this.DependOn<IPlayer>(() => GetParent().GetChildren().OfType<IPlayer>().Single());
|
||||
#endregion
|
||||
|
||||
#region Exports
|
||||
@@ -53,12 +56,51 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
|
||||
private Vector3 _knockbackDirection = Vector3.Zero;
|
||||
|
||||
private Vector3 _currentTarget = Vector3.Zero;
|
||||
|
||||
private Timer _thinkTimer;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
_enemyLogic = new EnemyLogic();
|
||||
_enemyLogic.Set(_enemyStatResource);
|
||||
_enemyLogic.Set(this as IEnemy);
|
||||
_enemyLogic.Set(Player);
|
||||
|
||||
NavAgent.VelocityComputed += NavAgent_VelocityComputed;
|
||||
NavAgent.TargetReached += NavAgent_TargetReached;
|
||||
|
||||
_thinkTimer = new Timer
|
||||
{
|
||||
WaitTime = 1f
|
||||
};
|
||||
AddChild(_thinkTimer);
|
||||
_thinkTimer.Timeout += NavAgent_TargetReached;
|
||||
_thinkTimer.Start();
|
||||
}
|
||||
|
||||
private void NavAgent_TargetReached()
|
||||
{
|
||||
NavAgent.TargetPosition = _currentTarget;
|
||||
}
|
||||
|
||||
private void NavAgent_VelocityComputed(Vector3 safeVelocity)
|
||||
{
|
||||
if (CurrentHP <= 0)
|
||||
return;
|
||||
|
||||
var lookDir = GlobalPosition - safeVelocity;
|
||||
var leveledLookDir = new Vector3(lookDir.X, Position.Y, lookDir.Z);
|
||||
if (leveledLookDir.DistanceTo(GlobalPosition) > 0.2f)
|
||||
LookAt(new Vector3(lookDir.X, Position.Y, lookDir.Z), Vector3.Up);
|
||||
|
||||
_knockbackStrength = _knockbackStrength * 0.9f;
|
||||
MoveAndCollide(safeVelocity + (_knockbackDirection * _knockbackStrength));
|
||||
}
|
||||
|
||||
public void SetTarget(Vector3 target)
|
||||
{
|
||||
Task.Delay(TimeSpan.FromSeconds(1.5)).ContinueWith(_ => _currentTarget = new Vector3(target.X, -1.75f, target.Z));
|
||||
}
|
||||
|
||||
public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false, bool ignoreDefense = false, bool ignoreElementalResistance = false)
|
||||
@@ -80,26 +122,29 @@ public partial class Enemy : RigidBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
|
||||
EnemyModelView.PlayHitAnimation();
|
||||
_enemyLogic.Input(new EnemyLogic.Input.Alerted());
|
||||
|
||||
if (Player.EquippedWeapon.Value.WeaponTags.Contains(WeaponTag.SelfDamage))
|
||||
Player.Stats.SetCurrentHP(Player.Stats.CurrentHP.Value - 5);
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveToLocation(Vector3 target, float delta)
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
NavAgent.TargetPosition = target;
|
||||
var targetPosition = NavAgent.GetNextPathPosition();
|
||||
if (CurrentHP <= 0)
|
||||
return;
|
||||
|
||||
var velocity = (targetPosition - GlobalTransform.Origin).Normalized() * 2f * delta;
|
||||
var lookAtDir = GlobalTransform.Origin - velocity;
|
||||
var lookAtPosition = new Vector3(lookAtDir.X, GlobalPosition.Y, lookAtDir.Z);
|
||||
var nextPathPosition = NavAgent.GetNextPathPosition();
|
||||
var movementDelta = 2f * (float)delta;
|
||||
|
||||
if (GlobalPosition.DistanceTo(target) > 1.0f && !velocity.IsEqualApprox(Vector3.Zero) && !Position.IsEqualApprox(lookAtPosition))
|
||||
LookAt(lookAtPosition + new Vector3(0.001f, 0.001f, 0.001f), Vector3.Up);
|
||||
var newVelocity = GlobalPosition.DirectionTo(nextPathPosition) * movementDelta;
|
||||
|
||||
if (NavAgent.AvoidanceEnabled)
|
||||
NavAgent.Velocity = newVelocity;
|
||||
else
|
||||
NavAgent_VelocityComputed(newVelocity);
|
||||
|
||||
var isWalking = _enemyLogic.Value is EnemyLogic.State.Patrolling or EnemyLogic.State.FollowPlayer;
|
||||
|
||||
EnemyModelView.RotateModel(GlobalTransform.Basis, -Player.CurrentBasis.Z, isWalking);
|
||||
_knockbackStrength = _knockbackStrength * 0.9f;
|
||||
MoveAndCollide(velocity + (_knockbackDirection * _knockbackStrength));
|
||||
}
|
||||
|
||||
public void Knockback(float impulse, Vector3 direction)
|
||||
|
||||
Reference in New Issue
Block a user