Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

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:
    486
    Use raycasting. Rigid bodies are not made for small Bodies going several hundred meters per second
     
  8. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,193
    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