I am not sure why collisions are not working all the time. I am using rigid bodies and tried different colliders (capsule, cube, sphere) and When I fire Sometimes they move and most of the time they don’t go anywhere.
here is my bullet fire code, it’s set to 75 speed. I tried different speeds but still no love:
shellClone = Instantiate(turretShell, transform.position, transform.rotation);
shellClone.velocity = transform.forward * speed; //speed= 75
If colliders move too fast, they might ‘quantum tunnel’ through… At one frame the body is on one side of the target (not colliding) and on the other it’s already passed cleanly through, and no collision is detected…
You can try setting the rigidbody collision mode to ‘continuous’ or ‘continuous dynamic’… those are less realistic, but they use sweep testing to detect collisions of fast-moving objects… if the collision is for a projectile, I guess it doesn’t matter if the reacion isn’t very realistic, since it’s gonna explode anyways
Hope this helps
Cheers
You can also use raycasting to detect a virtual hit. If the projectile is moving fast enough that you can’t see it, or don’t need to actually see it moving, then instead of instantiating the projectile just cast a ray from the gun and use the raycast info to tell you what object has been hit. This is another way to avoid the tunneling issue that HarvesteR mentioned.
Thanks HarvestR I tried the three different collisions modes and it was still hit and miss but mostly miss (95% of the time). I put the collision modes differently on the bullet and also the target but still no luck.
Tool55 I would like to see the bullets however I think if the collisions are going into Quantum Mechanics(I guess this is a bug) I might have to use the raycasting technique (ugh new function to me). Is raycasting the standard method for 1st and 3rd person shooter’s because of this collision problem?
Well, it’s not really a bug. It’s just the nature of the beast. The game updates every frame, but a fast moving object can pass through a collider in less time than that, so it goes undetected. I think you’ll find that for bullets, raycasting is the standard method. You can also slow down your projectile or make it a bit larger until your problem goes away.
However, don’t be afraid of raycasting. I was new to all of this a year ago and now I use raycasting all the time. It’s really not too difficult and it’s probably one of the most useful tools in the box. The scripting reference gives some decent examples:
// Raycast up to 100 meters forward
function Update () {
var hit : RaycastHit;
if (Physics.Raycast (transform.position, -Vector3.up, hit, 100.0)) {
var distanceToGround = hit.distance;
}
}
This is directly from the reference for detecting height above the ground. In your case, instead of hit.distance, you would use hit.collider to tell you which collider was hit, or hit.point for what point in World Space was hit. And you would use Vector3.forward. The example above shoots the ray downward. The “hit” variable stores all kinds of info about what was hit and where, which you can access through scripting.
Hopefully someone with more expertise than me will kick in here and give you other ideas, but this is how I would approach it to start. It might even be possible to cast a ray from the projectile itself and detect the hit.distance to tell when a collision is imminent, but this might be an expensive way to go from a performance standpoint. I’m not sure about that.
Awesome Tool55 I’ll use that method…trying it out now. I tired launching a barrage of bullets ( a group of 3 with a yield of .1 in between) and it worked but its kind of cheesy…
You can combine physical projectiles and raycasting if you want… that I think would yield nicer results…
Have the projectiles raycast into their forward vector… the length of the ray should be their velocity magnitude, so that at each frame, the projectile is looking one frame ahead to see if it will hit.
If you get a hit then, just spawn a squib or explosion at the ray’s hit position.
Happy shooting!
Cheers
EDIT: Just saw that Tool55 ninja’ed me to this idea
It’s not so heavy performance-wise… raycasting is VERY optimized, since it’s one of the most used features on a game engine… well, I can’t vouch for it if you wanna do one of them ‘the sky is black with arrows’ scenes… but it should work for a reasonable amount of projectiles
Good to know, HarvesteR. Wasn’t sure about the efficiency issue. Also, great idea about using a short raycast. (velocity magnitude) that you mentioned. Makes it simple. That way, any RaycastHit means an imminent collision. Happy shooting, Subvertio.
By the way, if you use HarvesteRs short raycast idea and you don’t care what’s hit, the raycasting becomes really easy. This is from the scripting reference:
function Update () {
var fwd = transform.TransformDirection (Vector3.forward);
if (Physics.Raycast (transform.position, fwd, 10)) {
print ("There is something in front of the object!");
}
}
You really only need the RaycastHit variable if you need additional information. You can use the above code directly on your projectile. Just shorten the ray length from 10 to whatever you want, then use Destroy() to kill your projectile and Instantiate() to replace it with an explosion. Leaving out the RaycastHit variable has the added value of saving a bit on performance.