using UnityEngine; using Saltosion.OneWeapon.Enemies; namespace Saltosion.OneWeapon.AI.Behaviours { public class Wander : AIBehaviour { public float WalkingDistance; public float MinWalkingDistance; public float SubjectRadius; public float StopLength; private Vector2 Target; private float StopTime; private bool Stopped = true; private void Start() { StopTime = Time.time; } public override bool CanBehave(Enemy subject) { return true; } public override bool Execute(Enemy subject) { Vector2 SubjectPosition = (Vector2)subject.transform.position; if ((Target - SubjectPosition).magnitude > SubjectRadius) { subject.StartMovingTo(Target); CurrentStatus = "Move"; Stopped = false; return true; } 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, '{subject.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"; } subject.StopMoving(); return false; } } }