Search Unity

Question Bullets go through colliders

Discussion in 'Scripting' started by johnc81, Jul 12, 2020.

  1. johnc81

    johnc81

    Joined:
    Apr 24, 2019
    Posts:
    142
    Hello,

    I am attempting to build a top-down shooter where the bullets will ricochet off the walls for infinity. I am having real difficulty getting my bullets to stop going through my colliders. I have done every Google search and tried different things:

    1. My walls are done using a Tilemap. I have tried the tilemap collider which didn't work. I then removed that and added box colliders to the walls.
    2. I have added rigidbody 2D components to the wall colliders above and my bullet also has a circle collider 2D and rigidbody 2D. The Collision Detection for both the rigidbodies is set to Continuous.
    3. I had a go at changing the Project Settings > Time > Fixed Timestep which actually worked, but had a negative impact on my player rotation, so I had to remove it.
    4. I have read every thread I could find and watched countless YouTube videos on raycasts. Unfortunately, the majority of these are for 3D and as much as I try to manipulate the code examples, they either give errors or don't seem to do anything at all.

    I am really struggling with this. It seems like raycasts might be the solution, but I have no idea how to implement it and can't find a suitable 2D tutorial about it.

    Here is the code I have now, which is letting bullets through the walls, like water through a sieve!

    The Player_Shooting script is attached to the player object
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Player_Shooting : MonoBehaviour
    6. {
    7.     [SerializeField] private Transform _firePoint;
    8.     [SerializeField] private GameObject _bulletPrefab;
    9.     [SerializeField] private float _bulletForce;
    10.        
    11.     private void Update() {
    12.         if (Input.GetButtonDown("Fire1")) {
    13.             Shoot();
    14.         }
    15.     }
    16.  
    17.     private void Shoot() {
    18.         GameObject bullet = Instantiate(_bulletPrefab, _firePoint.position, _firePoint.rotation);
    19.         Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
    20.         rb.AddForce(_firePoint.right * _bulletForce, ForceMode2D.Impulse);
    21.     }
    22. }
    The Bullet_Bounce script is attached to the instantiated bullet:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Bullet_Bounce : MonoBehaviour {
    6.     [SerializeField] private Rigidbody2D _rb;
    7.     private Vector3 _lastVelocity;
    8.  
    9.     private void Update() {
    10.         _lastVelocity = _rb.velocity;
    11.     }
    12.  
    13.     private void OnCollisionEnter2D(Collision2D other) {
    14.         var speed = _lastVelocity.magnitude;
    15.         var direction = Vector3.Reflect(_lastVelocity.normalized, other.contacts[0].normal);
    16.         _rb.velocity = direction * Mathf.Max(speed, 0f);
    17.     }
    18. }
    If anyone could assist me with this, I would really appreciate it.

    Many Thanks,

    J
     
  2. WarmedxMints

    WarmedxMints

    Joined:
    Feb 6, 2017
    Posts:
    1,035
    Have you tried setting the collision detection to continuous?
     
  3. johnc81

    johnc81

    Joined:
    Apr 24, 2019
    Posts:
    142
    Hi,

    Yes, collision detection in both the bullet and wall rigidbody are set to continuous, but the bullets still go through most of the time. Sometimes I manage to get a few ricochet before they break through, but they always eventually break through the walls.

    Many Thanks,

    John
     
  4. GameDevSK

    GameDevSK

    Joined:
    Jan 3, 2020
    Posts:
    3
    Please try with tag
     
  5. johnc81

    johnc81

    Joined:
    Apr 24, 2019
    Posts:
    142
    Hi,

    I changed it to the following and it still doesn't work. All the box colliders on the walls have the "Wall" tag applied:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Bullet_Bounce : MonoBehaviour {
    6.     [SerializeField] private Rigidbody2D _rb;
    7.     private Vector3 _lastVelocity;
    8.  
    9.     private void Update() {
    10.         _lastVelocity = _rb.velocity;
    11.     }
    12.  
    13.     private void OnCollisionEnter2D(Collision2D other) {
    14.         if (other.gameObject.CompareTag("Wall")) {
    15.             var speed = _lastVelocity.magnitude;
    16.             var direction = Vector3.Reflect(_lastVelocity.normalized, other.contacts[0].normal);
    17.             _rb.velocity = direction * Mathf.Max(speed, 0f);
    18.         }
    19.     }
    20. }
     
  6. MrWhiteGorilla

    MrWhiteGorilla

    Joined:
    Oct 3, 2020
    Posts:
    2
    hello john,

    I am facing the same problem here too, have you figured out a solution?
     
  7. Max-om

    Max-om

    Joined:
    Aug 9, 2017
    Posts:
    499
    Use raycasting. Rigid bodies are not made for small Bodies going several hundred meters per second
     
  8. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    21,183
    You just cast a ray from the previous location of the bullet to the current location checking for colliders.
     
    Chubzdoomer likes this.
  9. johnc81

    johnc81

    Joined:
    Apr 24, 2019
    Posts:
    142
    Hi,

    As mentioned above, I got around this by using raycasts.

    Cheers,

    J