Search Unity

Detecting Collisions on Instantiated Object?

Discussion in 'Scripting' started by JakeBilbe, Nov 9, 2015.

  1. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    I've done a bit of research but I couldn't find anything to what I'm looking for, I need to instantiate GameObjects and then have them check if they are colliding with another. I can't use OnCollisionEnter as it only works on moving Objects even with IsKinematic enabled. I also can't use OnTriggerEnter. I read up on Bounds.Intersects and it sounds perfect although from what I understand I need to be able to have the GameObject I believe it to be intersecting with? Is there anything like this where I don't need to have the GameObject referenced.
     
  2. Mr_Teels

    Mr_Teels

    Joined:
    Jul 14, 2015
    Posts:
    14
    What do you wanna know? Do the Instantiatet Objekts collide with each other or with some other different Objects?
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    OnCollisionEnter and OnTriggerEnter works. If you're not getting the trigger messages you need, check the collision action matrix at the bottom of this page. For OnCollisionEnter to work, at least one of the objects need to have a non-kinematic rigidbody.

    The bounds of a collider (or renderer) define an axis-aigned box, ie. a box that lies along the world axes. So if your instantiated object is ever rotated in any way, the intersects-check will be way too lenient about what's inside or not.

    If you post what you're trying to do exactly, it'll be a lot easier to give advice, but the general idea is to learn the physics system and use it.
     
  4. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    See what I'm doing is spawning in Map Pieces that will never move and stay static, the way that I'm doing this is by using child objects that are Connectors, the code is for the Connectors to check if they are colliding with another object, if they are then I want to disable a script on this Connector as it means it's connecting to another Piece of the map.

    I've tried OnCollision but from what I've read and understand it needs to be on a moving object same as OnTrigger, the only rotation I have on my objects is at 90Degree angles if that.

    Though I went ahead and played with Intersect last night by storing an Old copy of the list of Connectors and checking them against the new to find out but I wasn't able to get gameObject.renderer.bounds to work... I enabled auto code complete just in-case I was doing something wrong but even that couldn't find it so I'm not sure if I'm meant to be referencing something here?

    ----

    Just to clear it up though in-case it was a bit confusing above is create a randomly generated map made from prefabs. I have Rooms, Paths and Corridors, at the moment I'm only using the first two. Each of these has a Cube GameObject called a Connector with a script attached dictating what type of Piece it is.

    I'm creating an initial spawn room for the player and then building off of that, every time I generate a new piece I find all of the Connectors and add them to a list and then check through to see which have been used and remove them from the list, but I now want to be able to check if the Connector is colliding or in the same space as another Connector as it'd be used.
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    gameObject.renderer has been deprecated, so that's probably your issue. You'll want to GetComponent<MeshRenderer> or GetComponent<SkinnedMeshRenderer> to get the component you're looking for.


    That being said, kinematic trigger colliders does not have to move to generate trigger messages. If you instantiate a trigger collider (of any type) inside of a kinematic trigger collider, you will get a trigger message:

    Code (csharp):
    1. /*
    2.     * This script is placed on a cube positioned at (0.5, 0, 0)
    3.     * IT has a Box Collider that's a trigger, and a rigidbody that's got
    4.     * isKinematic = true and useGravity = false
    5.     */
    6.  
    7. void Awake() {
    8.     //Create a new GameObject with the same trigger and rigidbody settings as this one
    9.     GameObject obj = new GameObject("Cube with collider");
    10.     var bCol = obj.AddComponent<BoxCollider>();
    11.     bCol.isTrigger = true;
    12.  
    13.     var rb = obj.AddComponent<Rigidbody>();
    14.     rb.isKinematic = true;
    15.     rb.useGravity = false;
    16. }
    17.  
    18. void OnTriggerEnter(Collider other) {
    19.     //This will fire
    20.     Debug.Log("trigger enter!");
    21. }
    Just checked this, it works as intended.
     
    rubaun and JakeBilbe like this.
  6. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    Ah thank you, will these work by adding a Mesh Component without a Mesh attached or will the object need to have a Mesh to be used?

    I setup a RigidBody earlier with Kinematic set manually and it didn't seem to work but I'll give it another go now, thank you.
     
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    If you're using Mesh Colliders, note that they have to be set to Convex to be able to be triggers.

    Since you're just checking to see if your connectors are matchin, I'd use box colliders that match the connectors as good as possible.
     
  8. JakeBilbe

    JakeBilbe

    Joined:
    Jun 10, 2015
    Posts:
    57
    I went with Box Colliders, though I think the OnTrigger is called after the code that Generates the map so it's not working too well. I kind of need to either check if it's overlapping in the main Generator script or be able to have it check itself instantaneously.
     
  9. brainwipe

    brainwipe

    Joined:
    Aug 21, 2017
    Posts:
    78
    For anyone coming to this much later on, it is because the OnTrigger method is called in the next frame - not when you instantiate it. If you instantiate right now then the OnTrigger won't fire until the next loop. You have two options:

    1. Keep the object invisible and then let it decide whether to become visible next frame.
    2. (better) Use Physics.CheckBox (or which ever collider is best) before you instantiate.
     
    MassimoFrancesco likes this.