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

64 lines
2.4 KiB
C#
Raw Permalink Normal View History

2019-08-04 15:44:44 +02:00
using UnityEngine;
2019-08-14 16:17:48 +02:00
using Saltosion.OneWeapon.Enemies;
2019-08-04 15:44:44 +02:00
namespace Saltosion.OneWeapon.AI.Behaviours {
2019-08-14 18:05:41 +02:00
[RequireComponent(typeof(Enemy))]
2019-08-04 15:44:44 +02:00
public class Wander : AIBehaviour {
2019-08-18 20:32:07 +02:00
public float MaxWalkingDistance;
2019-08-04 15:44:44 +02:00
public float MinWalkingDistance;
public float SubjectRadius;
public float StopLength;
2019-08-14 18:05:41 +02:00
private Enemy Enemy;
2019-08-04 15:44:44 +02:00
private Vector2 Target;
private float StopTime;
private bool Stopped = true;
private void Start() {
2019-08-14 18:05:41 +02:00
Enemy = GetComponent<Enemy>();
2019-08-04 15:44:44 +02:00
StopTime = Time.time;
}
2019-08-14 18:05:41 +02:00
public override bool CanBehave() {
2019-08-04 15:44:44 +02:00
return true;
}
2019-08-14 18:05:41 +02:00
public override void Execute() {
Vector2 SubjectPosition = (Vector2)Enemy.transform.position;
2019-08-04 15:44:44 +02:00
if ((Target - SubjectPosition).magnitude > SubjectRadius) {
2019-08-14 18:05:41 +02:00
Enemy.StartMovingTo(Target);
2019-08-04 15:44:44 +02:00
CurrentStatus = "Move";
Stopped = false;
2019-08-14 18:05:41 +02:00
return;
2019-08-04 15:44:44 +02:00
} 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) {
2019-08-14 18:05:41 +02:00
Debug.LogWarning($"Wander behaviour took over 100 tries to find a wander position, '{Enemy.name}' is stuck!");
2019-08-04 15:44:44 +02:00
break;
}
2019-08-18 20:32:07 +02:00
float Distance = MinWalkingDistance + (MaxWalkingDistance - MinWalkingDistance) * Random.value;
2019-08-04 15:44:44 +02:00
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";
}
2019-08-14 18:05:41 +02:00
Enemy.StopMoving();
2019-08-04 15:44:44 +02:00
}
}
}