void Update() { // copy properties to projection all the time // (in case they are modified after creating it) agent.speed = speed; agent.angularSpeed = angularSpeed; agent.acceleration = acceleration; agent.stoppingDistance = stoppingDistance; agent.autoBraking = autoBraking; agent.radius = radius; agent.obstacleAvoidanceType = quality; agent.avoidancePriority = priority; agent.autoRepath = autoRepath; // copy position: transform in Update, rigidbody in FixedUpdate if (rigidbody2D == null || rigidbody2D.isKinematic) { transform.position = NavMeshUtils2D.ProjectTo2D(agent.transform.position); } // stuck detection if (IsStuck()) { // stop agent movement, reset it to current position agent.ResetPath(); agent.transform.position = NavMeshUtils2D.ProjectTo3D(transform.position); Debug.Log("stopped agent because of collision in 2D plane"); } }
void FixedUpdate() { // copy position: transform in Update, rigidbody in FixedUpdate if (rigidbody2D != null && !rigidbody2D.isKinematic) { rigidbody2D.MovePosition(NavMeshUtils2D.ProjectTo2D(agent.transform.position)); } }
void LateUpdate() { // copy position again, maybe NavMeshAgent did something new if (rigidbody2D == null || rigidbody2D.isKinematic) { transform.position = NavMeshUtils2D.ProjectTo2D(agent.transform.position); } }
bool IsStuck() { // stuck detection: get max distance first (best with collider) float maxdist = 2; // default if no collider if (collider2D != null) { var bounds = collider2D.bounds; maxdist = Mathf.Max(bounds.extents.x, bounds.extents.y) * 2; } // stuck detection: reset if distance > max distance float dist = Vector2.Distance(transform.position, NavMeshUtils2D.ProjectTo2D(agent.transform.position)); return(dist > maxdist); }
void FixedUpdate() { // copy properties to projection all the time // (in case they are modified after creating it) agent.speed = speed; agent.angularSpeed = angularSpeed; agent.acceleration = acceleration; agent.stoppingDistance = stoppingDistance; agent.autoBraking = autoBraking; agent.radius = radius; agent.obstacleAvoidanceType = quality; agent.avoidancePriority = priority; agent.autoRepath = autoRepath; // copy projection's position var rb = GetComponent <Rigidbody2D>(); if (rb != null && !rb.isKinematic) { rb.MovePosition(NavMeshUtils2D.ProjectTo2D(agent.transform.position)); } else { transform.position = NavMeshUtils2D.ProjectTo2D(agent.transform.position); } // stuck detection: get max distance first (best with collider) float maxdist = 2; // default if no collider if (GetComponent <Collider2D>()) { var bounds = GetComponent <Collider2D>().bounds; maxdist = Mathf.Max(bounds.extents.x, bounds.extents.y) * 2; } // stuck detection: reset if distance > max distance float dist = Vector2.Distance(transform.position, NavMeshUtils2D.ProjectTo2D(agent.transform.position)); if (dist > maxdist) { // stop agent movement, reset it to current position agent.ResetPath(); agent.transform.position = NavMeshUtils2D.ProjectTo3D(transform.position); Debug.Log("stopped agent because of collision in 2D plane"); } }
void Update() { // copy position: transform in Update, rigidbody in FixedUpdate if (rigidbody2D == null || rigidbody2D.isKinematic) { transform.position = NavMeshUtils2D.ProjectTo2D(agent.transform.position); } // stuck detection if (IsStuck()) { // stop agent movement, reset it to current position agent.ResetPath(); agent.transform.position = NavMeshUtils2D.ProjectTo3D(transform.position); Debug.Log("stopped agent because of collision in 2D plane"); } }
// based on: https://docs.unity3d.com/ScriptReference/AI.NavMesh.SamplePosition.html public static bool SamplePosition(Vector2 sourcePosition, out NavMeshHit2D hit, float maxDistance, int areaMask) { NavMeshHit hit3D; if (NavMesh.SamplePosition(NavMeshUtils2D.ProjectTo3D(sourcePosition), out hit3D, maxDistance, areaMask)) { hit = new NavMeshHit2D { position = NavMeshUtils2D.ProjectTo2D(hit3D.position), normal = NavMeshUtils2D.ProjectTo2D(hit3D.normal), distance = hit3D.distance, mask = hit3D.mask, hit = hit3D.hit }; return(true); } hit = new NavMeshHit2D(); return(false); }
public static bool Raycast(Vector2 sourcePosition, Vector2 targetPosition, out NavMeshHit2D hit, int areaMask) { if (NavMesh.Raycast(NavMeshUtils2D.ProjectTo3D(sourcePosition), NavMeshUtils2D.ProjectTo3D(targetPosition), out NavMeshHit hit3D, areaMask)) { hit = new NavMeshHit2D { position = NavMeshUtils2D.ProjectTo2D(hit3D.position), normal = NavMeshUtils2D.ProjectTo2D(hit3D.normal), distance = hit3D.distance, mask = hit3D.mask, hit = hit3D.hit }; return(true); } hit = new NavMeshHit2D(); return(false); }