0
\$\begingroup\$

I have attached a script to an empty GameObject to instantiate a prefab and the script is:

using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using UnityEngine;

public class Circles : MonoBehaviour
{
    [SerializeField] float Xmax;
    [SerializeField] float Xmin;
    [SerializeField] float Ymax;
    [SerializeField] float Ymin;

    [SerializeField] float outsideMaxsize;
    [SerializeField] float outsideMinsize;
    float insideMaxsize;
    float insideMinsize;


    public GameObject[] enemy;
    GameObject enemyObject;

    int enemyNo;

    
    float Xpos;
    float Ypos;
    float outsideSize;
    float insideSize;

  

    // Start is called before the first frame update
    void Start()
    {
        enemyNo = Random.Range(0, 4);
      
      instantiator();
    }

    // Update is called once per frame
    void Update()
    {
     
    }
    public void instantiator()
    {
        Xpos = Random.Range(Xmin, Xmax);
        Ypos = Random.Range(Ymin, Ymax);

        outsideSize = Random.Range(outsideMinsize, outsideMaxsize);

        Vector2 circlePos = new Vector2(Xpos, Ypos);
        transform.position = circlePos;
        
        
        enemyObject = GameObject.Instantiate(enemy[enemyNo], transform.position, transform.rotation,transform.parent) as GameObject;
            
        var enemies = enemyObject.transform;
        var outsideComponent = enemies.GetChild(0);
        var insideComponent = enemies.GetChild(1);
        outsideComponent.transform.localScale=new Vector2(outsideSize, outsideSize);
        insideMaxsize = outsideSize * 0.5f;
        insideMinsize = 0.15f;
        insideSize = Random.Range(insideMinsize, insideMaxsize);
        insideComponent.transform.localScale = new Vector2(insideSize, insideSize);

        enemyNo = Random.Range(0, 4);
    }
}

And I have attached a script to the prefab which is being instantiated and that script is:

 using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class destroyer : MonoBehaviour
{
    
    Circles circles;

    CircleCollider2D collider1;
    Collider2D collider2;


    private void Start()
    {
      

        circles = FindObjectOfType<Circles>();

        print("1 max"+collider1.bounds.max);
        print("1 min" + collider1.bounds.min);
        print("2 max" + collider2.bounds.max);
        print("2 min" + collider2.bounds.min);
        

    }
 
    private void OnEnable()
    {
        collider1 = gameObject.transform.GetChild(0).GetComponent<CircleCollider2D>();
        collider2 = gameObject.transform.GetChild(1).GetComponent<Collider2D>();
    }

   
    void OnTriggerStay2D(Collider2D other)
    {
        print("star max"+other.bounds.max);
        print("star min" + other.bounds.min);

        if (collider1.bounds.Contains(other.bounds.max) && collider1.bounds.Contains(other.bounds.min))
       {
            
            if (other.bounds.Contains(collider2.bounds.max) && other.bounds.Contains(collider2.bounds.min))
            {
                  
                    Destroy(other.gameObject);
                    Destroy(gameObject);
                    circles.instantiator();
                
            }

        }
    }
}

the problem is that the z axis bounds of the colliders are coming out to be 15.8 when the prefab is instantiated and when I drag the prefab to scene then the z axis bounds of the collider is 0. I want the z axis bounds of the colliders to be 0 when the prefab is instantiated

\$\endgroup\$
  • \$\begingroup\$ Getting the colliders with gameObject.transform.GetChild(0).GetComponent<Collider2D>() is very messy. You should use serialized fields and select the colliders in the Inspector, e.g. [SerializeField] private Collider collider1; \$\endgroup\$ – Kevin Aug 4 at 22:14
  • \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$ – Mohammad AL - Haque Aug 5 at 14:11
0
\$\begingroup\$

The simplest way to fix this is to spawn your prefab at a position that places its children in the same z-plane as the objects you're hoping to detect.

So for example if the object you want to detect is at z=0, and your prefab's children are at z = 1 relative to their parent, and their parent isn't scaled in the z axis or rotated in the x/y axes, then you would need to spawn the parent at z = -1 to cancel-out the child colliders' offsets so they'll sit at the z = 0 plane.

Since you haven't shown us enough details of your setup for us to tell you exactly what position values to change, another option is to exclude Z from consideration in your test. We can do this by adding an extension method:

public static class PhysicsExtensions {
    public static bool Envelops2D(this Bounds a, Bounds b) {
        return (b.max.x <= a.max.x)
             & (b.max.y <= a.max.y)
             & (b.min.x >= a.min.x) 
             & (b.min.y >= a.min.y);
    }
}

Then you can change your if clauses to...

if (collider1.bounds.Envelops2D(other.bounds))
{            
    if (other.bounds.Envelops2D(collider2.bounds))
    {                  
         Destroy(other.gameObject);
         Destroy(gameObject);
         circles.instantiator();                
    }
}

Note that this is using only the bounding rectangles of your colliders, not their actual shapes. So for example this will say a radius-8 circle collider at (0, 0) envelops a radius-1 circle collider at (7, 7), even though that second circle is completely outside the first, but still inside its bounding rectangle. You can use radius and distance checks instead of bounds checks if you want to take the circular shape of the colliders into account.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.