64 lines
2.4 KiB
C#
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 MaxWalkingDistance;
|
|
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 + (MaxWalkingDistance - 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();
|
|
}
|
|
}
|
|
}
|