I am currently working on a small project where the player will shoot enemies and score points. I have been implementing the shooting mechanic and ran into issues with Unity's collision detection. I am instantiating the bullet the exact same way for both the player and enemy, the only difference in their scripts is how the direction of the bullet is obtained. Anyways, I have a bullet behavior script that is meant to handle collisions with the bullet and the world environment. Currently, the bullet works almost as intended, with the bullets colliding with the player, enemy, and world environment. My problem occurs when the Player shoots several bullets in succession. If during this quick succession the Enemy fires a bullet towards the player, it will phase right through the player.
This is my current script for handling the bullets behavior.
public class bulletScript : MonoBehaviour
{
private ParticleSystem bulletParticle;
public bool spawnedByPlayer = true; // Flag to indicate if spawned by player
public Transform impactPrefab;
// Start is called before the first frame update
void Start()
{
// Logic to ignore layers depending on object that spawned this instance.
int playerLayer = LayerMask.NameToLayer("Player");
int enemyLayer = LayerMask.NameToLayer("Enemy");
int bulletLayer = LayerMask.NameToLayer("Bullet");
int ignoreLayer = spawnedByPlayer ? playerLayer : enemyLayer;
int otherLayer = spawnedByPlayer ? enemyLayer : playerLayer;
Physics2D.IgnoreLayerCollision(gameObject.layer, bulletLayer);
Physics2D.IgnoreLayerCollision(bulletLayer, ignoreLayer, true);
Physics2D.IgnoreLayerCollision(bulletLayer, otherLayer, false);
bulletParticle = GetComponent<ParticleSystem>();
}
// Update is called once per frame
void Update()
{
}
void OnCollisionEnter2D(Collision2D collision)
{
ContactPoint2D contact = collision.contacts[0];
Vector2 impactDirection = -contact.normal; // Reverse the normal vector to face away from the collision
Quaternion rotation = Quaternion.FromToRotation(Vector2.right, impactDirection);
Vector2 position = contact.point;
Transform impactObj = Instantiate(impactPrefab, position, rotation);
ParticleSystem bulletParticleSystem = GetComponentInChildren<ParticleSystem>();
ParticleSystem[] impactParticleSystems = impactObj.GetComponentsInChildren<ParticleSystem>();
ParticleSystem.MainModule bulletMain = bulletParticleSystem.main;
foreach (ParticleSystem impactParticleSystem in impactParticleSystems)
{
ParticleSystem.MainModule impactMain = impactParticleSystem.main;
impactMain.startColor = bulletMain.startColor;
}
Destroy(gameObject);
}
}
My suspicion is that this has something to do with Unity's physics engine and the collision detection. Mainly because once the Player stops shooting in quick succession, everything works as intended. My only idea to solve this collision issue was to decrease the TimeStep value in the Time Manager, hoping that it would increase the number of collision detection calls. This had no effect. My bullet collision components are fairly small, which was another possibility I explored, however, I came to the same conclusion that because the collisions are detected in all other situations it probably isn't the source of the problem.
Edit I was able to alleviate this issue by going into the object inspection tab of my projectile prefab and including the "Player" layer in the Layer Overrides of the Rigidbody2D component. While I would consider this a temporary fix, I didn't want to submit it as an answer because it doesn't help me understand the cause of my problem.
Thanks to anyone that answers or has suggestions!