Multiple raycasts in same fixedupdate

So I have a bullet script that goes very fast using a rigidbody and then calculates collisions using raycasts inside fixedupdate. It works great except for this one detail. If you manage to shoot the same object twice in the same fixedupdate, it will only perform the check on the first hit. I know I am bad at explaining…

Inside FixedUpdate() I have a linecast from the bullet position to its previous position (or opposite rather). If the linecast returns true I have a ‘RaycastHit hits RaycastAll(…)’ and a ‘foreach(RaycastHit hit in hits)’ This is where my problem occurs. The RaycastAll only returns a raycasthit the first time it hits an object, so only one raycasthit per object. I need to redo the checks every time an object is hit.

I tried making a for/foreach/while loop that raycasted from the last hit point towards the bullets current position until there was no more objects between it, but this didn’t work any different for some reason.

A raycast will always hit a single object only once, no matter how many intersections you’ll have. If you want to know all hit points on a concave object you have to use multiple raycasts. Just start a new raycast at the last hit point. You should move the new startpoint a bit forward to prevent hitting the same spot again. You can do this in a while loop until you don’t get a “new” hit. It’s probably better to use a for loop to setup a max hit count to prevent a possible infinite loop.

Vector3 pos;
Vector3 dir;

for(int i = 0; i < MaxHitCount; i++)
{
    RaycastHit hit;
    if (Physics.Raycast(pos, dir, out hit))
    {
        // calculate new starting point for the next raycast
        pos = hit.point + dir*0.1f;
        // handle your hit
    }
    else
    {
        // No more hits so stop the loop
        break;
    }

}

um, how fast are you shooting wowsers.

fixedupdate runs once per frame. most games need to be run at minimum 30fps to run ok.

that means your shooting something twice in less than 1/30th of a second which is fast lol.

an actual 6,000 rpm 6 barreled minigun is 100 rounds a second and your firing at least 60? like you might want to tone that shit down a bit hoss. :stuck_out_tongue:

But to address your issue

so firstly, i’m only vaguely understanding what your saying but it sounds possible your leading bullet is actually destroying instances of bullets behind it if your doing any kind of destruction calls. I think your first bullets raycastall trigger might be actually pinging off a follow up round.

i’m trying to understand you are you saying your bullet is flying through the air and you ray cast behind it to see if it “passed through” something to hit it? Like its some kind of explosive round?

why are you using raycasts to do collision detection with a rigidbody anyways?

rigidbodies should use OnCollsionEnter() to react to the object they hit.

raycasts should be for laserbeam style weapons. These are normally referred to in FPS game parlance as “hitscan” weapons because the moment you fire they scan to see what was in front of the gun and hit it. they suffer zero bullet drop/travel time etc. They are laser beams, instantly traveling exactly straight.

If your going to use rigidbodies for a bullet thats fine but make sure you slow the bullets to a quasi reasonable value. if the bullets are travelling too fast it’s possible for them completely pass through an object between frame movement and not be “caught” colliding. Turning on continous dynamic collision detection for the rigidbody can technically fix this but it also means a huge performance hit.

I think I found the error, I feel so stupid now. I changed for(int c = 0; c < 1; c++) to c < 2 and it worked flawlessly.

I also added an offset, since it was shorten than having an if statement and storing an extra position. However this didn’t change the behaviour of the script!

Anyway for anyone who is interrested, here is a pretty nice bullet script:
void FixedUpdate() {
Ray diray = new Ray(prev, transform.position-prev);

//		if(Physics.Linecast(prev, transform.position, mask))	{	//Uncomment to add .000000001 FPS and use slightly less RAM
			Vector3 start = prev;

			for(int c = 0; c < 2; c++)	{
				Debug.Log(c);

				RaycastHit hit = new RaycastHit();
				if(Physics.Linecast(start, transform.position, out hit, mask))	{
					Debug.DrawLine(start, hit.point, new Color(Random.value, Random.value, Random.value));
					Instantiate(debugObj, hit.point, Quaternion.LookRotation(hit.normal));

					//If hit.gameobject has a script that implements IDamagable, TakeDMG(damage)
					//If(wallbang.Contains(hit.tag)) Do stuff
					//Else if ricochet.contains(hit.tag) Do other stuff

					c = 0;
					start = hit.point + diray.direction*.01f;
					Instantiate(debugObj, start, Quaternion.LookRotation(diray.direction));
//					continue;

					//If loop hasn't continued yet, DestroyImmidiate(gameObject);
				} else {
					c = 2;
					Debug.DrawLine(start, transform.position, Color.green);
					break;
				}
			}
//		}

		Debug.Break();
		prev = transform.position;
	}