public Vector2 GetBestNextCorner(Vector2 from, Vector2 target) { //non-collidable, keep moving if (Corners.Count == 0) { return(target); } //find closest corner Corner closestCorner = Corners[0]; float bestDistance = 1000f; foreach (Corner corner in Corners) { Vector2 selfDifference = corner.Position - from; float distanceToSelf = selfDifference.sqrMagnitude; if (distanceToSelf < bestDistance) { closestCorner = corner; bestDistance = distanceToSelf; } } //can detach directly if (closestCorner.CanSeePoint(target)) { return(target); } //are we on same sector if (GetATanCorners(target, out Vector2 leftCornerTo, out Vector2 rightCornerTo)) { if (closestCorner.Position == leftCornerTo || closestCorner.Position == rightCornerTo) { return(target); } } //evaluate neighbors float closeDistance = (target - closestCorner.Position).sqrMagnitude; float leftDistance = (target - closestCorner.LeftPosition).sqrMagnitude; float rightDistance = (target - closestCorner.RightPosition).sqrMagnitude; //check if we stand on best corner if (closeDistance <= leftDistance && closeDistance <= rightDistance) { return(target); } //move to better neighbor if (leftDistance < rightDistance) { return(closestCorner.LeftPosition); } else { return(closestCorner.RightPosition); } }