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. Dismiss Notice

Bug bounds.Intersects returning false positives.

Discussion in 'Physics' started by stakensj, Jun 14, 2023.

  1. stakensj

    stakensj

    Joined:
    Oct 23, 2020
    Posts:
    35
    hello! I have a problem where I am instantiating an object, but before I do that I instantiate a version of it called checker, if it detects that the checker collides with another object, it deletes the checker, otherwise, it deletes the checker and instantiates the real object.

    however, no matter where I put the object, it comes back as a false positive, even after I decreased the collider size so their borders don't collide.

    can anyone help me figure out what is going on?

    Video (checkers don't disappear for testing purposes):


    Script:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class genericscript : MonoBehaviour
    6. {
    7.     public List<GameObject> PARTSQUOTA = new List<GameObject>();
    8.  
    9.     public List<PART_BASE> SCRIPTS = new List<PART_BASE>();
    10.  
    11.     public LayerMask clickLayerMask;
    12.  
    13.     public Vector3 here;
    14.  
    15.     public float gridSize = 1f;
    16.     private const float adjustmentOffset = 0.5f;
    17.  
    18.     private Vector3 LOCATION;
    19.  
    20.     public GameObject car;
    21.  
    22.     public GameObject CURRENTPART;
    23.  
    24.  
    25.  
    26.     void Start()
    27.     {
    28.  
    29.     }
    30.  
    31.  
    32.  
    33.  
    34.     void Update()
    35.     {
    36.         if (Input.GetMouseButtonDown(0))
    37.         {
    38.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    39.             if (Physics.Raycast(ray, out RaycastHit hitInfo, Mathf.Infinity, clickLayerMask))
    40.             {
    41.                 LOCATION = CalculateGridPosition(hitInfo.point - ray.direction * adjustmentOffset);
    42.                
    43.  
    44.                 Vector3 gridPosition = CalculateGridPosition(hitInfo.point);
    45.  
    46.  
    47.                      if (!CheckCollision())
    48.                      {
    49.                         Instantiate(CURRENTPART, LOCATION, Quaternion.identity, transform);
    50.                         PART_BASE CURRENTSCRIPT = CURRENTPART.GetComponent<PART_BASE>();
    51.  
    52.  
    53.  
    54.                         if (CURRENTSCRIPT != null)
    55.                         {
    56.                             SCRIPTS.Add(CURRENTSCRIPT);
    57.                         }
    58.                        
    59.                    
    60.                     }
    61.  
    62.             }
    63.         }
    64.     }
    65.  
    66.     void OnDrawGizmos()
    67.     {
    68.         Gizmos.color = Color.yellow;
    69.         Gizmos.DrawCube(LOCATION, here);
    70.     }
    71.    
    72.     private Vector3 CalculateGridPosition(Vector3 position)
    73. {
    74.     Vector3 localPosition = transform.InverseTransformPoint(position);
    75.  
    76.     float x = Mathf.Round(localPosition.x / gridSize) * gridSize;
    77.     float y = Mathf.Round(localPosition.y / gridSize) * gridSize;
    78.     float z = Mathf.Round(localPosition.z / gridSize) * gridSize;
    79.  
    80.     return transform.TransformPoint(new Vector3(x, y, z));
    81. }
    82.  
    83.  
    84. private bool CheckCollision()
    85. {
    86.     GameObject Checker = Instantiate(CURRENTPART, Vector3.zero, Quaternion.identity, this.transform);
    87.     Checker.transform.position = LOCATION;
    88.     Checker.name = "checker";
    89.  
    90.     Collider[] colliders = car.GetComponentsInChildren<Collider>();
    91.     Collider[] cursorColliders = Checker.GetComponentsInChildren<Collider>();
    92.  
    93.     Debug.Log("Number of colliders in car: " + colliders.Length);
    94.     Debug.Log("Number of colliders in checker: " + cursorColliders.Length);
    95.  
    96.     foreach (Collider cursorCollider in cursorColliders)
    97.     {
    98.  
    99.         foreach (Collider collider in colliders)
    100.         {
    101.                 if (cursorCollider.bounds.Intersects(collider.bounds))
    102.                 {
    103.                     Destroy(Checker); // Destroy the temporary object
    104.                     Debug.Log("Collision detected");
    105.                     return true; // Collision detected
    106.                 }
    107.         }
    108.     }
    109.  
    110.     Destroy(Checker); // Destroy the temporary object
    111.     Debug.Log("No collision detected");
    112.     return false; // No collision detected
    113. }
    114.  
    115.  
    116.  
    117.    
    118.  
    119. }
     
  2. stakensj

    stakensj

    Joined:
    Oct 23, 2020
    Posts:
    35
    a video showing the colliders a bit better:
     
  3. stakensj

    stakensj

    Joined:
    Oct 23, 2020
    Posts:
    35
    also it always comes back as not colliding if I remove
    this.transform
    from
    GameObject Checker = Instantiate(CURRENTPART, Vector3.zero, Quaternion.identity, this.transform);
     
  4. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    1,834
    A collider's bounds is calculated as an AABB, that is, a big box aligned with the axes in world space, not the box that makes the tightest possible fit nor the local space. This can cause a lot of unexpected false positive "hits" if the objects have any rotation or complex shape.

    If you use the Instantiate method like this:
    Instantiate(CURRENTPART, Vector3.zero, Quaternion.identity, this.transform);
    then the new object becomes a child of
    this.gameObject
    at the same location (localPosition of Vector3.zero). Colliders automatically don't collide with their parents/children, they're all treated as part of the same complex object. And if you remove the parent argument, it's made at the world origin (position of Vector3.zero) instead.

    Instead of trying to instantiate some sort of checker, just use the Physics.CheckBox or Physics.BoxCast methods (or the other primitive shapes) to look for potential conflicts before spawning.
     
    Last edited: Jun 14, 2023
  5. stakensj

    stakensj

    Joined:
    Oct 23, 2020
    Posts:
    35
    that works, but I need it also to work for other shapes, like a T or a C, will bringing the object after it was instantiated not as a child towards all the other ones work?