Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

How do a create a bomb that can't pass through different floors

Discussion in 'Scripting' started by tawak3500, Aug 10, 2016.

  1. tawak3500

    tawak3500

    Joined:
    Oct 28, 2013
    Posts:
    77
    Hi everyone,

    I was wondering whats the best way to create a bomb that can't access certain areas. For instance if a character is hiding beyond the wall, it wouldn't make sense for the bomb to go through it. I'm using unity2D btw. Thanks in advance.
     
  2. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Do you want to stop the bomb itself from going through a wall or the explosion?
     
  3. tawak3500

    tawak3500

    Joined:
    Oct 28, 2013
    Posts:
    77
    just the explosion. Right now the wall prevents the bomb from going through.
     
  4. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    How are you actually handling your explosion? This will make a difference.

    Off the top of my head I would consider sending out a bunch of line casts in all directions from the point of explosion. That way you can only damage the first thing each line cast touches.

    For a more sophisticated system you could use a particle system and enable global collisions.
     
  5. alexisrabadan

    alexisrabadan

    Joined:
    Aug 26, 2014
    Posts:
    82
    You could try using the overlap sphere to get all objects that will be affected by the blast, then raycast to each affected object to see if a wall (or other static object) is in the way. There are a lot of solutions to this problem, just depends if you care more about realism or performance.
     
    jimroberts and Kiwasi like this.
  6. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    If you're talking about blast then raycasts will sort that out...
     
  7. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    This is the easiest and fastest solution to implement. There is a more efficient way to do it using spatial partitioning but it seems like overkill for a 2D game.
     
  8. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The physics system implements its own spatial partitioning that overlap sphere and overlap circle take advantage of. You'd need a pretty specialised game before it makes sense to implement your own.
     
  9. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    Do you have more information on the spatial partitioning for Unity? I can't seem to find anything. I assume PhysX is using some form of tree structure(Octree or AABB tree) instead of BSP. I should have clarified my response.
     
    Last edited: Aug 10, 2016
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    3D uses PhysX. 2D uses Box2D. Can't tell you much more beyond that. But check out the third party docs for more info.
     
  11. tawak3500

    tawak3500

    Joined:
    Oct 28, 2013
    Posts:
    77
    Sorry for my inactivity but I'm still having problems. This is my current code but I'm getting bunch of nullreferenceException errors and it still passes through walls.
    Code (CSharp):
    1.     void Update()
    2.     {
    3.         colliding = Physics2D.OverlapCircleAll (this.transform.position, explosionRadius);
    4.  
    5.         explosionCountdown -= Time.deltaTime;
    6.         PixelRotation();
    7.  
    8.         if (explosionCountdown <= 0)
    9.             Explode(true);
    10.     }
    Code (CSharp):
    1.     void Explode(bool timeout)
    2.     {
    3.         if (explosive && explosionCountdown <= 0 && timeout == true  || explosive && timeout == false)
    4.         {
    5.             foreach (Collider2D hit in colliding)
    6.             {
    7.                 RaycastHit2D hit2d = Physics2D.Raycast(transform.position, hit.transform.position - transform.position,explosionRadius);
    8.                 Debug.Log (hit2d.collider.tag);
    9.  
    10.                 if (hit2d.collider != null)
    11.                 {
    12.                     if (hit2d.collider.tag == "Wall")
    13.                     {
    14.                         break;
    15.                     }
    16.                     if (hit2d.collider.tag == "Player" || hit2d.collider.tag == "bomb")
    17.                     {
    18.                         if(hit.tag == "Player")
    19.                         {
    20.  
    21.                             _rb2d.GetComponent<Rigidbody2D>().AddExplosionForce(explosionForce, hit.GetComponent<Rigidbody2D>(), explosionRadius, -1);
    22.                             hit.gameObject.GetComponent<PlayerScript>().isAlive = false;
    23.                             Destroy (hit.gameObject, .5f);
    24.                         }
    25.                         if(hit.tag == "bomb")
    26.                         {
    27.                             hit.gameObject.GetComponent<AmmoProperties>().explosionCountdown = .08f;
    28.                             _rb2d.GetComponent<Rigidbody2D>().AddExplosionForce(explosionForce,hit.GetComponent<Rigidbody2D>(), explosionRadius, -1);
    29.                         }
    30.                     }
    31.                     else
    32.                     {
    33.                         return;
    34.                     }
    35.                     return;
    36.                 }
    37.  
    38.             }
    39.             DoTweenShakePosition ();
    40.             Particle ("explosionParticle");
    41.             Destroy (gameObject);
    42.         }
    43.     }
     
  12. tawak3500

    tawak3500

    Joined:
    Oct 28, 2013
    Posts:
    77
    I think I got it :
    Code (CSharp):
    1.     void Explode(bool timeout)
    2.     {
    3.         if (explosive && explosionCountdown <= 0 && timeout == true  || explosive && timeout == false)
    4.         {
    5.             foreach (Collider2D hit in colliding)
    6.             {
    7.                 RaycastHit2D hit2d = Physics2D.Raycast(transform.position, hit.transform.position - transform.position,explosionRadius, explosionLayermask);
    8.  
    9.                 if(hit2d.collider != null)
    10.                 {
    11.                     Debug.Log (hit2d.collider.tag);
    12.  
    13.                     if (hit2d.collider.tag == "Wall")
    14.                     {
    15.                         break;
    16.                     }
    17.                     if (hit.tag == "Player" || hit.tag == "bomb")
    18.                     {
    19.                         if(hit.tag == "Player")
    20.                         {
    21.  
    22.                             _rb2d.GetComponent<Rigidbody2D>().AddExplosionForce(explosionForce, hit.GetComponent<Rigidbody2D>(), explosionRadius, -1);
    23.                             hit.gameObject.GetComponent<PlayerScript>().isAlive = false;
    24.                             Destroy (hit.gameObject, .5f);
    25.                         }
    26.                         if(hit.tag == "bomb")
    27.                         {
    28.                             hit.gameObject.GetComponent<AmmoProperties>().explosionCountdown = .08f;
    29.                             _rb2d.GetComponent<Rigidbody2D>().AddExplosionForce(explosionForce,hit.GetComponent<Rigidbody2D>(), explosionRadius, -1);
    30.                         }
    31.                     }
    32.                 }
    33.             }
    34.             DoTweenShakePosition ();
    35.             Particle ("explosionParticle");
    36.             Destroy (gameObject);
    37.         }
    38.     }
     
  13. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    line 17 is redundant
     
  14. tawak3500

    tawak3500

    Joined:
    Oct 28, 2013
    Posts:
    77
    Yea I noticed that thanks. I tested it again and it works sometimes and sometimes it doesnt.
     
  15. tawak3500

    tawak3500

    Joined:
    Oct 28, 2013
    Posts:
    77
    Ok seems to work now:
    Code (CSharp):
    1. public void Explosion(Collider2D[] colliding, ParticleSystem particle)
    2.     {
    3.         foreach (Collider2D hit in colliding)
    4.         {
    5.             RaycastHit2D[] hit2d = Physics2D.RaycastAll(transform.position, hit.transform.position - transform.position, explosionRadius, explosionLayermask);
    6.             foreach (RaycastHit2D raycastHit in hit2d)
    7.             {
    8.                 if (raycastHit.collider != null)
    9.                 {
    10.                     if (raycastHit.collider.tag == "Wall")
    11.                     {
    12.                         break;
    13.                     }
    14.                     if (raycastHit.collider.tag == "Player")
    15.                     {
    16.  
    17.                         //raycastHit.collider.GetComponent<Rigidbody2D>().AddExplosionForce(explosionForce, hit.GetComponent<Rigidbody2D>(), explosionRadius, -1);
    18.                         raycastHit.collider.gameObject.GetComponent<PlayerScript>().isAlive = false;
    19.                         Destroy(raycastHit.collider.gameObject, .5f);
    20.                     }
    21.                     if (raycastHit.collider.tag == "bomb")
    22.                     {
    23.                         //raycastHit.collider.GetComponent<Rigidbody2D>().AddExplosionForce(explosionForce,hit.GetComponent<Rigidbody2D>(), explosionRadius, -1);
    24.                         raycastHit.collider.gameObject.GetComponent<AmmoProperties>().explosionCountdown = .08f;
    25.                     }
    26.                 }
    27.             }
    28.             DoTweenShakePosition();
    29.             Particle(particle);
    30.             Destroy(gameObject);
    31.         }
    32.     }
    and I put this method inside update
     
    galloping_bull likes this.