- Home /
answer in original question
[SOLVED]: bullet passing through object in specific condition
Hi there,
I have first person shooting game where the camera is fixed. The player shoots at moving shapes. -I have a cube that has a rigidbody and a bunch of child colliders that break it up into zones. -I also have invisible walls that prevent the shapes from moving off camera or too close to the camera (and therefore the bullet must always pass through one or more invisible walls to get to a shape). The invisible walls are box colliders. -When the bullet is fired, I use IgnoreCollision on all the invisible walls with the bullet. -The bullet has a rigidbody with continuous dynamic collision detection and a sphere collider -The cube has discrete collision detection (rigidbody/collider setup mentioned above)
This works fine when the shape is near the center of the screen or has distance from the invisible walls. However if the shape is very close to an invisible wall and very close to the edge of the screen (sharp angle from projectile), the bullet will pass through the shape and hit the wall behind it. I have attached to both of them this "DontGoThroughThings.js" script that creates raycasts every frame to ensure that it will not pass through things:
// http://www.unifycommunity.com/wiki/index.php?title=DontGoThroughThings
#pragma strict
var layerMask : LayerMask; //make sure we aren't in this layer
var skinWidth : float = 0.1; //probably doesn't need to be changed
private var minimumExtent : float;
private var partialExtent : float;
private var sqrMinimumExtent : float;
private var previousPosition : Vector3;
private var myRigidbody : Rigidbody;
//initialize values
function Awake() {
if (name.Contains("zone")) {
myRigidbody = transform.parent.rigidbody;
}
else {
myRigidbody = rigidbody;
}
previousPosition = myRigidbody.position;
minimumExtent = Mathf.Min(Mathf.Min(collider.bounds.extents.x, collider.bounds.extents.y), collider.bounds.extents.z);
partialExtent = minimumExtent*(1.0 - skinWidth);
sqrMinimumExtent = minimumExtent*minimumExtent;
}
function FixedUpdate() {
//have we moved more than our minimum extent?
var movementThisStep : Vector3 = myRigidbody.position - previousPosition;
var movementSqrMagnitude : float = movementThisStep.sqrMagnitude;
if (movementSqrMagnitude > sqrMinimumExtent) {
var movementMagnitude : float = Mathf.Sqrt(movementSqrMagnitude);
var hitInfo : RaycastHit;
//check for obstructions we might have missed
if (Physics.Raycast(previousPosition, movementThisStep, hitInfo, movementMagnitude, layerMask.value)) {
if (hitInfo.transform.gameObject.tag!="InvisWall") {
myRigidbody.position = hitInfo.point - (movementThisStep/movementMagnitude)*partialExtent;
}
}
}
previousPosition = myRigidbody.position;
}
Does anyone have any insight into why this might happen?
Thanks, Candace
EDIT
Solution: Removed invisible walls and changed shapes to follow a waypoint system for movement.
Answer by Meater6 · Jun 15, 2011 at 09:13 PM
Well, if you want to, a easier way to solve this would be to make the gun fire Raycasts instead of actual bullets. Then you just make the invisible walls a different layer that is not affected by these raycasts, but the targets still are. Also, for what reason do you have the invisible walls for? Would it be easier just making a Waypoint system that the targets follow? But back to your original question. It might pass through because the bullets are moving to fast, or your frame rate is to low or a combination. I've had problems like this on very slow computers. There could be other reasons such as you are using trigger colliders (I doubt that though) instead of actual colliders.
Hi, thanks for the reply.
I have contemplated just using raycasts but it is a requirement of the game that gravity forces the player to aim a little higher at long ranges to simulate reality. The invisible walls are used so that the shapes (which are in random motion) will not go out of the view of the camera. However, you are right perhaps there is another way to do it without the invisible walls and I think that is what I'll try. Although with 20 shapes on the screen I am not sure how efficient it would be to have them check their location every frame to ensure they are in view. If you have any other ideas on this I would like to hear. I also am unfamiliar with the Waypoint system. I will look more into that.
Thanks, Candace
Waypoint systems are easy enough. For this, you randomly generate Vector3's or transforms that are limited in your field of view. Then move your target to its random position, maybe through Vetor3.Lerp. Check every frame if it is close enough to its Vector3. If it is, repeat the process with a new point. That's kind of all there is to it. And no, checking your objects positions every frame should not be overly costly
Awesome, worked out a way system and was able to remove those invisible walls! No bullet collision issues! Thank you.
I would like it if you mark this as the correct answer. It shows others that this question has been answered and that this is the correct one. Also, it gives +15 rep. Glad it works. :)
Answer by Chrisg · Jun 17, 2011 at 02:04 PM
Just off the top of my head, but:
Set bullet as a trigger by default
Fire bullet from behind wall, so it must travel all the way through it.
Set up OnTriggerExit() on the walls that turns bullet trigger off, which should re-enable physics detection(and thus destroy the bullet if it hits the back invisible wall)
Thanks for the reply. I tried this and different variations of your solution but was getting some odd results.