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(); 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(); } } }