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

[SOLVED] Strange behavior with OverlapBox

Discussion in 'Scripting' started by spelafort, Feb 21, 2020.

  1. spelafort

    spelafort

    Joined:
    May 8, 2017
    Posts:
    37
    Hi,

    I'm trying to make a 'failsafe' for a spawning system. If two things spawn on top of one another, I want to destroy the second thing (will replace this later with just moving the second thing, but for now..!). It's acting quite strangely. Sometimes it seems to work fine, especially at first, but when batches of objects are spawned at the same time it doesn't seem to work at all. Here's my code, I'm just calling it from Start:

    Code (CSharp):
    1.     IEnumerator checkForOverlaps()
    2.     {
    3.  
    4.         Collider[] hitColliders = Physics.OverlapBox(gameObject.transform.position, gameObject.GetComponent<BoxCollider>().bounds.extents, Quaternion.identity, LayerMask.GetMask("Default"));
    5.      
    6.         yield return new WaitForFixedUpdate();
    7.         if(hitColliders.Length != 0)
    8.         {
    9.             Debug.Log("GAMEOBJECT DESTROYED!!!");
    10.             Destroy(gameObject.transform.parent.gameObject);
    11.         }
    12.     }
    13.  
    14.     void OnDrawGizmos()
    15.     {
    16.         Gizmos.color = Color.red;
    17.  
    18.             Gizmos.DrawWireCube(transform.position, transform.localScale);
    19.     }
    I was guessing that it was a timing problem, hence the coroutine. But even when I tried putting a manual 2 second delay in, it doesn't seem to work. Weirder yet, the gizmo for the box's extents doesn't seem to change regardless of the Vector3 I put for the extents-- even if I put 100,100,100, the gizmo stays the same (although it does effectively kill all objects immediately after spawning them).

    Hope that makes sense.

    Any help would be appreciated.
     
    luizero00 likes this.
  2. unit_dev123

    unit_dev123

    Joined:
    Feb 10, 2020
    Posts:
    989
    post screenshot
     
  3. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Do you call that function from within OnFixedUpdate() ?

    Other than that, potentially, I'm not sure where's the problem.

    You do an instantiation with a simple list or an array of objects. No need for a coroutine.
    "Have I something in this list that I should instantiate?
    Ok, let's check whether these things will collide with anything already existing."

    One by one, you create a proper overlap box for each, test for an overlap, then simply not instantiate an object if it overlaps.

    As for your other question, there is nothing weird about it, you're setting the gizmo size to a transform.localScale vector which is probably (1, 1, 1) -- why do you think it should be anything else? Your overlap box has nothing to do with transform.localScale.

    [edit]
    btw, if there is a timing problem, this could be because you're instantiating in Update, and check for the overlap in FixedUpdate. the two methods aren't synced to each other, yet colliders and rigidbodies belong to physics and probably need a full cycle to settle down. though this is just a wild guess on my part, what I explained above should work no matter what.
     
    Last edited: Feb 23, 2020
  4. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    Why would you need a screenshot? What's worthy of a screenshot?
    Please, please, you're not helping by saturating a question with an answer that isn't answering at all.
    Now it shows '1' to everybody, and this is why nobody has paid any attention to it ever since you've responded.
    I've seen you around and your one-liners really do not help anybody. I'm glad you're trying, but don't.
     
  5. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    OP,
    I would really like to see your full implementation.

    Among other things, you shouldn't really call GetComponent in Update or FixedUpdate. It's not a light thing to do in every frame.

    You would normally make a spawning factory script, that is keeping track of all the objects that it spawned.
    You call this script's method with a request to spawn a list of objects.
    Inside that method, for every object found in the list, you test that new box with the previous ones and omit those whose colliders appear to overlap. Note that this will behave suboptimally for any large amount of objects.
    But I won't go into details of a better algorithm, other than suggesting that it requires a Quad Tree.
     
  6. unit_dev123

    unit_dev123

    Joined:
    Feb 10, 2020
    Posts:
    989
    Ty for your feedback sir, i will try to be more careful
     
  7. spelafort

    spelafort

    Joined:
    May 8, 2017
    Posts:
    37
    hi, thanks for the response(s)! I don't call it within Update or OnFixedUpdate. I was actually calling it from Start() originally, but you may have pinpointed the problem there. What I thought was strange was that even if I manually added a WaitForSeconds to test if it was a timing issue, it still didn't work.
    It wasn't in a coroutine before, actually, I was just trying to fix what I assumed to be a timing issue.
    localScale is actually being (potentially) changed at instantiation. Now that I think of it, this might be the likeliest cause of the issue, since the gizmo is never being changed... perhaps my scaling is being done after my overlap testing.
    Will post in a few hours when I'm back on that computer :) thanks again for the ideas!
     
  8. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,204
    By default, newly spawned objects are not synced with the physics world before the next pyhsics frame. Your coroutine would fix that, except that you're waiting after you've done the overlap box, which makes zero sense.

    Instead of waiting, you can just tell the physics system to sync changes after you've spawned the objects, by calling Physics.SyncTransforms. The order should be:

    1: Spawn all the objects
    2: Call Physics.SyncTransforms
    3: Check for overlaps.
     
  9. spelafort

    spelafort

    Joined:
    May 8, 2017
    Posts:
    37
    Worked like charm. Can't believe the solution was so simple. Thanks Baste/orionsyndrome!
     
  10. Zaddo

    Zaddo

    Joined:
    May 19, 2012
    Posts:
    76
    @Baste Thank you so much!!!! I have been searching for an answer to same problem for days.
     
    spelafort likes this.
  11. pRoFlT

    pRoFlT

    Joined:
    Dec 20, 2014
    Posts:
    27
    Unity 2019.4.13f1 (because we are all using it)
    That Physics.SyncTransforms didn't work for me :) I'm getting prefabs spawned into other prefab collider boxes? i have a gizmo drawing the OverlapBox and sometimes it works. sometimes i see two items on top of each other. and they are normally right after another in the spawn. a tree and a house. the tree spawns inside the house collider area. but the overlap box area shows it hitting the collider? ahh. so frustrating.

    Right now i have code in FixedUpdate, thinking i need physics to complete before checking collisions. So i place a prefab off map (0,-100,0). get bounds on collider from it. create an empty to move to a random spot. use OverlapBox to test for colliders with prefab collider bounds.size. place prefab in open spot. loop once, spawn prefab, place empty at random location, loop once check collider with prefab collider size, place in free spot. repeat.

    i put Physics.SyncTransforms in the main FixedUpdate loop so it would force run every FixedUpdate before i did prefab instantiate and collision check. and that didn't even help. Do i need collider on the empty object im using to OverlapBox with? I only use it for a position, rotation. i expect 0 collisions since the empty object has no colliders on it.

    my previous version where i would place the prefab and test collisions seemed to work better. but then i have prefabs jumping all over the map while loading. Looks funny. Thats why empty prefab to test with. Guess i could remove render while jumping around. then reset render. but prefabs have a lot of meshes on it.

    My next idea, which is crazy. is to create a locationspawned list. keep track of where im placing things. and test against that. Faster as i dont need physics to run the code. but i need to check if two vector3s are overlapping somehow. every search sends me to physics code.. 3D math ugh...i will figure it out this way. But then i also have to consider colliders already on the map. If i can test 2 vector3s for overlap or on top of. maybe distance between and size would be enough. i dont have to worry about y axis. only x and z. everything placed at y=0

    2 days into this mess.

    Any thoughts on this prefab in prefab issue? empty object my issue. ill try next. Thanks for the long read if you made it this far :)