BloodAndGore/Assets/Scripts/AI/Behaviours/Wander.cs

64 lines
2.4 KiB
C#

using UnityEngine;
using Saltosion.OneWeapon.Enemies;
namespace Saltosion.OneWeapon.AI.Behaviours {
[RequireComponent(typeof(Enemy))]
public class Wander : AIBehaviour {
public float WalkingDistance;
public float MinWalkingDistance;
public float SubjectRadius;
public float StopLength;
private Enemy Enemy;
private Vector2 Target;
private float StopTime;
private bool Stopped = true;
private void Start() {
Enemy = GetComponent<Enemy>();
StopTime = Time.time;
}
public override bool CanBehave() {
return true;
}
public override void Execute() {
Vector2 SubjectPosition = (Vector2)Enemy.transform.position;
if ((Target - SubjectPosition).magnitude > SubjectRadius) {
Enemy.StartMovingTo(Target);
CurrentStatus = "Move";
Stopped = false;
return;
} else if (!Stopped) {
Stopped = true;
StopTime = Time.time;
Target = SubjectPosition;
} else if (Time.time - StopTime > StopLength) {
// The AI is near the target, and has waited for StopTime.
// Now we pick a new target.
CurrentStatus = "Search";
int i = 0;
while ((Target - SubjectPosition).magnitude <= SubjectRadius) {
i++;
if (i > 100) {
Debug.LogWarning($"Wander behaviour took over 100 tries to find a wander position, '{Enemy.name}' is stuck!");
break;
}
float Distance = MinWalkingDistance + (WalkingDistance - MinWalkingDistance) * Random.value;
float Direction = Random.value * Mathf.PI * 2f;
Vector2 Delta = new Vector2(Mathf.Cos(Direction), Mathf.Sin(Direction)) * Distance;
RaycastHit2D Hit = Physics2D.Raycast(SubjectPosition + Delta.normalized * SubjectRadius, Delta.normalized, Distance);
if (Hit.rigidbody == null) {
Target = SubjectPosition + Delta;
}
}
} else {
CurrentStatus = "Stop";
}
Enemy.StopMoving();
}
}
}