v 4.1.1
Question
I am making an enemy with to main states: patrolling and seeking.
Currently, patrolling state is activated whenever is player out of chasing range. But I want to be activated at start and then if player gets closer it will be permanently switched to seeking state.
In short, i want to have patrolling state as like some kind of spawn state and if player gets closer he would be permanently chased down by an enemy.
The problem is that now, if player runs away from enemy, the enemy will switch back to patrolling state. Here is my physics process with all functions:
public override void _PhysicsProcess(double delta)
{
wallCheck.LookAt(new Vector3(player.Position.X, Position.Y, player.Position.Z), Vector3.Up); //raycast that detects walls
#region EYE LOOK
eyes.LookAt(new Vector3(player.Position.X, player.Position.Y, player.Position.Z), Vector3.Up);
Vector3 eyeRot = eyes.Rotation;
eyeRot.X = Mathf.Clamp(eyeRot.X, Mathf.DegToRad(-45), Mathf.DegToRad(45));
eyeRot.Y = Mathf.Clamp(eyeRot.Y, Mathf.DegToRad(-45), Mathf.DegToRad(45));
eyes.Rotation = eyeRot;
#endregion
if (stayTime > 0)
{
stayTime -= (float)delta;
Animations.Play(animIdle);
StateChange = false;
return;
}
var points = patrolPoints[_nextPointIndex].GlobalPosition;
var victim = player.GlobalTransform.Origin;
var gotoTarget = points;
if(!navAgent.IsTargetReachable())
{
if(TargetMid())
{
LookAt(new Vector3(player.GlobalPosition.X, GlobalPosition.Y, player.GlobalPosition.Z), Vector3.Up);
}
}
if (wallCheck.IsColliding())
{
var Interaction = wallCheck.GetCollider() as StaticBody3D;
if(Interaction != null)
{
Speed = 0f;
}
}
if (eyes.IsColliding())
{
var Interaction = eyes.GetCollider() as CharacterBody3D;
if(Interaction != null)
{
if (Interaction.IsInGroup("player"))
{
ChasingMode();
}
}
}
if(Patrolling())
{
PatrolMode();
}
#region PATH SETUP
var NextNavPoint = navAgent.GetNextPathPosition();
Velocity = (NextNavPoint - GlobalTransform.Origin).Normalized() * Speed;
#endregion
#region ROTATION
var rotation = new Quaternion(Basis).Normalized();
if(Velocity != Vector3.Zero)
{
LookAt(new Vector3(GlobalPosition.X + Velocity.X, GlobalPosition.Y, GlobalPosition.Z + Velocity.Z), Vector3.Up);
}
else if(Velocity == Vector3.Zero)
{
}
var targetRot = new Quaternion(Basis).Normalized();
Rotation = rotation.Slerp(targetRot, 0.15f).Normalized().GetEuler();
#endregion
MoveAndSlide();
}
public bool Patrolling()
{
return GlobalPosition.DistanceTo(player.GlobalPosition) > chaseRange;
}
public bool Seeking()
{
return GlobalPosition.DistanceTo(player.GlobalPosition) < chaseRange;
}
public bool TargetClose()
{
return GlobalPosition.DistanceTo(player.GlobalPosition) < atkRange;
}
public bool TargetMid()
{
return GlobalPosition.DistanceTo(player.GlobalPosition) < 5f;
}
public bool TargetFar()
{
return GlobalPosition.DistanceTo(player.GlobalPosition) > atkRange;
}
public void ChasingMode()
{
var points = patrolPoints[_nextPointIndex].GlobalPosition;
var victim = player.GlobalTransform.Origin;
var gotoTarget = points;
if(StateChange == true)
{
if(TargetFar())
{
//CHASING
Animations.Play(animRun);
Speed = defSpeed;
StateChange = false;
navAgent.TargetPosition = victim;
}
}
if(StateChange == true)
{
if(TargetClose())
{
//ATTACKING
Animations.Play(animAttack);
Speed = atkSpeed;
StateChange = false;
navAgent.TargetPosition = victim;
LookAt(new Vector3(player.GlobalPosition.X, GlobalPosition.Y, player.GlobalPosition.Z), Vector3.Up);
}
}
}
public void PatrolMode()
{
var points = patrolPoints[_nextPointIndex].GlobalPosition;
var victim = player.GlobalTransform.Origin;
var gotoTarget = points;
Patrol();
if(TargetFar())
{
//wALKING
Animations.Play(animWalk);
Speed = wondSpeed;
StateChange = false;
navAgent.TargetPosition = points;
}
if(StateChange == true)
{
if(TargetClose())
{
//STAYING
Animations.Play(animIdle);
//Speed = 0f;
StateChange = false;
navAgent.TargetPosition = points;
}
}
}
public void Patrol()
{
if (patrolPoints[_nextPointIndex].GlobalPosition.DistanceTo(GlobalPosition) < atkRange)
{
Speed = 0f;
stayTime = patience;
//walking = true;
_nextPointIndex++;
_nextPointIndex = _nextPointIndex % patrolPoints.Count; // Wrap from length (out of bounds) back to 0.
}
}
}
If some variable is unclear let me know.