Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Physics.OverlapSphere is giving me the wrong results

Discussion in 'Scripting' started by TheForsaken95, Jun 14, 2015.

  1. TheForsaken95

    TheForsaken95

    Joined:
    Aug 29, 2014
    Posts:
    30
    I know that this is my own user error here, but I cannot seem to fix this problem on my own. I've spent hours trying to find a work around, or just simply a solution to fix this problem.

    I am using Physics.OverlapSphere to access the position of all objects surrounding it. Basically this is a zombie that is supposed to walk towards whoever it decides to aggro. My script works flawlessly if there are 1 or 2 objects; The problem starts when I have 3+ objects that start next to it on the field.

    I use an integer to get the object within the array that overlapsphere returns, and with that integer I can make the referenced object chase me. When I make the object run so that it loses "sight" on a 3rd object somewhere off in the distance, the array changes and it screws up integer I was using, and it no longer references the object that I intended it to reference. It makes it do this weird thing where it alternates between me and the 2nd object every other frame, and it will just sit in one spot doing that. I have my code here, if anyone would be interested in helping me.

    Code (CSharp):
    1.     void Update () {
    2.         CharacterController playerController = GetComponent<CharacterController> ();
    3.  
    4.         //Creates a sphere surrounding the AI that acts as its vision range.
    5.         Collider[] visionArea = Physics.OverlapSphere (transform.position, visionRange, layerMask);
    6.         //Check to see if anything is in range to draw aggro.
    7.         if (visionArea.Length > 0) {
    8.             //If the AI is not currently chasing something, this will randomly choose just 1 target inside of the radius to chase.
    9.             if (aggro == false || target > visionArea.Length - 1) {
    10.                 target = Random.Range (0, visionArea.Length);
    11.                 aggro = true; //When aggro is true, it means the AI is currently chasing something.
    12.             }
    13.  
    14.             //Process chase movement. This causes the AI to chase the randomly selected target.
    15.             Vector3 targetPosition = visionArea [target].transform.position;
    16.             Vector3 rotationalPosition = new Vector3 (targetPosition.x, transform.position.y, targetPosition.z);
    17.             transform.LookAt (rotationalPosition);
    18.             moveDirection = transform.TransformDirection (Vector3.forward);
    19.             moveDirection *= movementSpeed;
    20.  
    21.         } else {
    22.             aggro = false;
    23.             moveDirection.x = 0.0f;
    24.             moveDirection.z = 0.0f;
    25.             print ("AI is not chasing");
    26.             /*if(Time.time > roamRate) {
    27.                 moveDirection = transform.TransformDirection (Vector3.forward);
    28.                 roamRate += roamRate;
    29.             }*/
    30.         }
    31.         moveDirection.y -= gravity * Time.deltaTime;
    32.         playerController.Move (moveDirection * Time.deltaTime);
    33.     }
    And on a side note, I have made myself absolutely certain that the RNG on that random number is not the cause of the problem. The random number stays the same at all times, the problem is when the array changes, it screws up the reference that the integer pointed to. I don't know how to fix this :(
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Instead of storing a reference to an outdated array index, store a reference to the Transform or GameObject of the target and then run checks against that particular object. If it's out of range or line of sight, then run your OverlapSphere check and establish a new target. This will save you a ton of overhead and performance.

    Something like this in pseudocode:
    Code (csharp):
    1.  
    2. if(target != null and distance to target is valid and target passes a line of sight check [maybe?]))
    3. {
    4.    chase them
    5. }
    6. else
    7. {
    8.    target = your current sphere check except assign the collider's Transform or GameObject, not the index into the array
    9. }
    10.  
     
    TheForsaken95 likes this.
  3. TheForsaken95

    TheForsaken95

    Joined:
    Aug 29, 2014
    Posts:
    30
    Thanks a lot GroZZler! That's twice you have solved a problem of mine today :)