/// <summary> /// Checks nearby for valid places for the drone to move. /// Valid places must be in front of the player, and not intersect any objects within a reasonable tolerance. /// Use radiusCheckRate and percentageThreshold to tweak what counts as a valid location. /// </summary> /// <param name="newpos"></param> /// <returns></returns> private bool FindNewMovePosition(out Vector3 newpos) { //We can't move if the ZED isn't initialized. if (!zedManager.IsZEDReady) { newpos = transform.position; return(false); } Vector3 randomPosition; // Look Around For a New Position //If the Drone is on the screen, search around a smaller radius. //Note that we only check the primary ZEDManager because we only want the drone to spawn in front of the player anyway. if (ZEDSupportFunctions.CheckScreenView(transform.position, zedManager.GetLeftCamera())) { randomPosition = UnityEngine.Random.onUnitSphere * UnityEngine.Random.Range(2f, 3f) + transform.position; } else //if the drone is outside, look around a bigger radius to find a position which is inside the screen. { randomPosition = UnityEngine.Random.onUnitSphere * UnityEngine.Random.Range(4f, 5f) + transform.position; } // Look For Any Collisions Through The ZED bool hit = ZEDSupportFunctions.HitTestAtPoint(zedManager.zedCamera, zedManager.GetLeftCamera(), randomPosition); if (!hit) { newpos = transform.position; return(false); } //If we spawn the drone at that world point, it'll spawn inside a wall. Bring it closer by a distance of ClearRadius. Quaternion directiontoDrone = Quaternion.LookRotation(zedManager.GetLeftCameraTransform().position - randomPosition, Vector3.up); Vector3 newPosition = randomPosition + directiontoDrone * Vector3.forward * ClearRadius; //Check the new position isn't too close from the camera. float dist = Vector3.Distance(zedManager.GetLeftCamera().transform.position, randomPosition); if (dist < 1f) { newpos = transform.position; return(false); } //Also check nearby points in a sphere of radius to make sure the whole drone has a clear space. if (ZEDSupportFunctions.HitTestOnSphere(zedManager.zedCamera, zedManager.GetLeftCamera(), newPosition, 1f, radiusCheckRate, percentageThreshold)) { newpos = transform.position; return(false); } //Return true if it's made it this far and out the location we chose. newpos = newPosition; return(true); }
/// <summary> /// Looks for a random point in a radius around itself. /// Upon collision, the point is moved slightly towards the camera and if its too far it's set to "maxSpawnDistance". /// A more thorough search is then done for any other obstacles around it, also, in a radius. /// If the number of collision doesn't exeeds the set threshold, then return true and output the new position. /// </summary> /// <returns><c>true</c>, if random spawn location was checked, <c>false</c> otherwise.</returns> /// <param name="newRandomPos">Random position.</param> private bool CheckRandomSpawnLocation(out Vector3 newRandomPos) { //We can't do anything if the ZED isn't initialized. if (!zedManager.IsZEDReady) { newRandomPos = Vector3.zero; return(false); } //Pick a screen position at random between 0.25 and 0.75. Vector2 randomScreenPoint = new Vector2(Random.Range(0.25f, 0.75f) * Screen.width, Random.Range(0.25f, 0.75f) * Screen.height); //Get the world position of that position in the real world Vector3 randomWorldPoint; bool foundWorldPoint = ZEDSupportFunctions.GetWorldPositionAtPixel(zedManager.zedCamera, randomScreenPoint, leftcamera, out randomWorldPoint); if (!foundWorldPoint) //We can't read depth from that point. { newRandomPos = Vector3.zero; return(false); } float firstDistance = Vector3.Distance(leftcamera.transform.position, randomWorldPoint); float newClearRadius; //Check that the distance isn't too far. if (firstDistance > maxSpawnDistance) { newClearRadius = firstDistance - maxSpawnDistance; } else { newClearRadius = clearRadius; } //If we spawn the drone at that world point, it'll spawn inside a wall. Bring it between you and that wall. Quaternion directionToCamera = Quaternion.LookRotation(leftcamera.transform.position - randomWorldPoint, Vector3.up); Vector3 closerWorldPoint = randomWorldPoint + directionToCamera * Vector3.forward * newClearRadius; //Check that distance isn't too close float secondDistance = Vector3.Distance(leftcamera.transform.position, closerWorldPoint); if (secondDistance < 1f) { newRandomPos = Vector3.zero; return(false); } //Also check nearby points in a sphere of radius=ClearRadius to make sure the whole drone has a clear space. if (ZEDSupportFunctions.HitTestOnSphere(zedManager.zedCamera, leftcamera, closerWorldPoint, 1f, radiusCheckRate, percentagethreshold)) { //Not clear. newRandomPos = Vector3.zero; return(false); } else { //Clear. newRandomPos = closerWorldPoint; return(true); } }