Ok, So I have been working on creating a Gun/Bullet script in unity, I have gotten to the point where I have the gun shooting and went to attempt bullet penetration, the only way I can think to do this is by making the sphere collider attached to the bullet a trigger when it collides with an object with the tag “Penetrable” The issue is it only works occasionally and it is really laggy, here is the code any help/ideas would be appriciated thanks in advance!
using UnityEngine;
using System.Collections;
public class BulletObject : MonoBehaviour {
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.tag == "Penetrable")
{
collider.isTrigger = true;
print (this.gameObject.name +" Has had it's spherecollider removed");
}
if (collision.gameObject.tag == "Terrain")
{
print (this.gameObject.name + " has hit the ground!");
Destroy (this.gameObject);
}
}
void OnCollisionExit(Collision collision)
{
if (collision.gameObject.tag == "Penetrable")
{
collider.isTrigger = false;
print (this.gameObject.name + " Has had it's spherecollider re-added");
}
}
}
Making a GO with a box collider set to trigger (our penetration collider)
Make it a child of the projectile and ensure the trigger covers the projectile and a distance in front of it
Put your collision code in a script using the penetration collider and change it to trigger enter/exit
What that will (hopefully) do is effectively check what is in front of the projectile and deactivate the collider prior to the projectile hitting it.
Points:
Depending on how many projectiles are fired at once it may hurt performance a bit? (Doubling the colliders in scene per projectile)
The distance in front of the projectile the trigger is checking will have to be a bit of trial and error - Depending on how fast your projectile is moving it may have to be pretty long to ensure it is monitoring far enough ahead that your movement between frames is covered.
Other option which may work with a bit more math is just use a trigger for the projectile and if it needs to ricochet, do your own math based on collision details and set the relevant velocity/angle
Is it only working sometimes? You might have an issue with a bullet passing through a collider without actually intersecting it.
Eg:
Frame 1: Bullet is on left side of collider
Frame 2: Bullet is going so fast it is on right side of collider without ever actually touching the collider.
If this is happening, you can try changing the rigidbody.collisionDetectionMode to Continuous or ContinuousDynamic and see if that helps. The only way I’ve seen to fix this problem for sure is to RayCast every frame and check to see if a collider would’ve been in the way. There’s an example DontGoThroughThings script you can look at if this is your problem.
If you think about the concept, it shouldn’t work. If you collide with an object, change the collider to a trigger. The key here being if you collide, you’ve already hit the wall so most of the time the forces on the rigidbody will still be exerted then it will lose it’s collider.
Making it a trigger doesn’t lose the ability for ‘ricochet’ - Using a rigidbody is a pretty bad way to simulate bullets but you can use Vector3.Reflect to mirror the velocity of the rigidbody when something enters the trigger. You’ll just need to figure out the normal direction of the colliders face that you hit.
It doesn’t work when I add a trigger and use that to make the sphere collider a trigger either though, infact it works better the first way(besides the lag)
well like Josh707 already said, and I will Quote him : “Using a rigidbody is a pretty bad way to simulate bullets”
I dont think that there is a elegant solution while sticking to the build in Physics system. Rigidbodys are good for slow moving projectiles like in Angry Birds for example, but it seams you want to for rifles, guns etc.
I have a code snippet somewhere that “bends” raycasts to follow a ballistic curve. If you whant I can try to find it and post the code here ( There is no ricocet or penetration in it but because its a Raycast its shouöd be simple to implemant )