using System.Threading.Tasks; using UnityEngine; using static UnityEditor.PlayerSettings; public class Target : MonoBehaviour { public BoxCollider targetMoveAbleArea; public LayerMask hitMask; public float moveSpeed = 1; public float rotateSpeed = 1; private Vector3 targetPos; private void Awake() { RandomSpawn(); } //private void Update() //{ // if (Input.GetKeyDown(KeyCode.F)) // { // RandomSpawn(); // } //} private void FixedUpdate() { var dir = targetPos - this.transform.position; if (dir.magnitude > .5f) { var targetRot = Quaternion.LookRotation(dir, Vector3.up); this.transform.rotation = Quaternion.Slerp(this.transform.rotation, targetRot, Time.fixedDeltaTime * rotateSpeed); this.transform.position += this.transform.forward * moveSpeed * Time.fixedDeltaTime; } else { SearchRandomTargetMovePos(); } } private void SearchRandomTargetMovePos() { GetRandomPosition(out var tmpPos); var randomMoveOffset = (tmpPos - this.transform.position).normalized * moveSpeed; if (!Physics.BoxCast(this.transform.position, .5f * Vector3.one, randomMoveOffset, this.transform.rotation)) { targetPos = tmpPos; } } private void RandomSpawn() { GetRandomPosition(out var pos); this.transform.position = pos; targetPos = pos; } private void GetRandomPosition(out Vector3 pos, int limit = 100) { pos = Vector3.one; if (limit < 0) return; var minPos = targetMoveAbleArea.bounds.min; var maxPos = targetMoveAbleArea.bounds.max; float randomF() { return Random.Range(0, 1.0f); } pos.x = Mathf.Lerp(minPos.x, maxPos.x, randomF()); pos.y = Mathf.Lerp(minPos.y, maxPos.y, randomF()); pos.z = Mathf.Lerp(minPos.z, maxPos.z, randomF()); var hits = Physics.OverlapBox(pos, .5f * Vector3.one, Quaternion.identity, hitMask, QueryTriggerInteraction.Collide); if (hits.Length > 0) { GetRandomPosition(out pos, --limit); } } private async void DebugR() { int i = 1000; while (--i > 0) { GetRandomPosition(out var pos); var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.position = pos; await Task.Yield(); } } }