Search Unity

Preventing Object Instantiation Inside Other Object

Discussion in 'Scripting' started by magnus0, Sep 5, 2018.

  1. magnus0

    magnus0

    Joined:
    Nov 20, 2017
    Posts:
    4
    First off, if I am confusing I apologize, I will clearing if I need to.
    Now... I want to be able to instantiate an object ONLY if the instantiated object will NOT collide with any previously placed objects.
    Think of a Tetris game, but instead of objects falling into place, you place them. The thing I want to prevent is placing an object that doesn't fit (shape wise).
    Any help would be appreciated. Thank you

    Oh, a few extra info:
    - Its a 3d game with a top down perspective.
    - I am not very experienced, if it wasn't clear
    - I am most familiar with C# (familiar being used lightly), but I will do the research to convert from Java if required... Not preferred but I'm not picky
     
    Last edited: Sep 5, 2018
  2. TimmyTheTerrible

    TimmyTheTerrible

    Joined:
    Feb 18, 2017
    Posts:
    186
    You could do this a couple of ways. If your objects can be approximated by the typical primitive shapes(sphere, capsule, box), then it's pretty easy. All you have to do use Physics.OverlapSphere/Box/Capsule and see if it returns any collisions.

    If your objects shape isn't one of these shapes, then your gonna have to probably setup an invisible collision prefab of some kind, and then use it to test spaces for collision.
     
    magnus0 and SparrowGS like this.
  3. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Timmy(TIMMAAAA) is right on the money, if a sphere is okay do the overlapSphere method.

    if you have oddly shaped objects use the objects mesh as a way to detect it.

    IE: Spawn an invisible collider with the objects mesh, wait a frame, see if OnCollisionEnter(or trigger, what ever) is called

    if yes -> can't spawn
    if no -> can spawn
     
    Joe-Censored and magnus0 like this.
  4. magnus0

    magnus0

    Joined:
    Nov 20, 2017
    Posts:
    4
    Thanks. I will give it a shot and see if it works (or see if I can muster the brain power to make it work).
     
  5. magnus0

    magnus0

    Joined:
    Nov 20, 2017
    Posts:
    4
    Alrighty then. I looked into the overlapbox and I understand how it works, but I don't know how to apply it to my script. I have made a few modifications and all have failed. So, below I have attached a combination of my current code with Unity's API. How would I modify this to work? Would I apply a modified version of MyCollisions() within the instantiation portion of the script (after line 22)?

    Code (CSharp):
    1. Ray ray;
    2.     RaycastHit hit;
    3.  
    4.     public GameObject collisionTestObj;
    5.  
    6.     bool m_Started;
    7.     public LayerMask m_LayerMask;
    8.  
    9. void FixedUpdate()
    10.     {
    11.  
    12.         ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    13.  
    14.         if(Physics.Raycast(ray, out hit))
    15.         {
    16.             GameObject colObj = hit.collider.gameObject;
    17.  
    18.             if (colObj.tag == "Ground")
    19.             {
    20.                 if (Input.GetMouseButtonDown(0))
    21.                 {
    22.                     GameObject obj = Instantiate(collisionTestObj, new Vector3(hit.point.x, hit.point.y, zLocation), Quaternion.identity) as GameObject;
    23.                 }
    24.             }
    25.         }
    26.  
    27.         MyCollisions();
    28.     }
    29.  
    30.  
    31.  
    32.     void MyCollisions()
    33.     {
    34.         Collider[] hitColliders = Physics.OverlapBox(gameObject.transform.position, transform.localScale / 2, Quaternion.identity, m_LayerMask);
    35.         int i = 0;
    36.  
    37.         while (i < hitColliders.Length)
    38.         {
    39.             Debug.Log("Hit : " + hitColliders[i].name + i);
    40.             i++;
    41.         }
    42.     }
    43.  
     
  6. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    On the first line of "MyCollisions" you're using gameObject.transform.position, i suspect you may want to use the ray hit point, but i don't know what this script is attached to (my guess is the player or an empty manager-style game object )

    you're also not doing anything with the information given, when you loop through the colliders, if you come across a collider that should block you from placing what you wanna place you need to report it to what spawns things.

    you need to either have a constant check in the update loop and update a bool to control the spawning
    or do the check when the player gives the order to spawn and respond only when needed.

    the biggest mistake you've done is place the whole thing in the FixedUpdate loop rather than the regular Update loop,
    the only time you want to read input in FixedUpdate is when you read Input.GetKey and equivalents(the ones that returns true WHILE the button is pressed),
    if you use the Up or Down variation you might miss a click, check the docs, it's (kinda) based on the update loop