Unreliable projectile::oncollision call
by Brian "Bazz" Staudinger · in Torque Game Engine · 01/01/2004 (2:08 pm) · 21 replies
Does anyone know why the projectile::oncollision call does not allways come.
Im useing the 1.2 demo , and im trying to play impulse keepie-uppy , its strange , sometimes I can see the explosion from the hit but "onCollision: does not get called,,it seems to hapen most when i shoot a falling target in mid air.
Is this a SDK Bug?
Has anyone else seen this or is it just me?
Im useing the 1.2 demo , and im trying to play impulse keepie-uppy , its strange , sometimes I can see the explosion from the hit but "onCollision: does not get called,,it seems to hapen most when i shoot a falling target in mid air.
Is this a SDK Bug?
Has anyone else seen this or is it just me?
#2
I put an echo into the "projectile::oncollision" function so that I can see if its getting called.
01/01/2004 (10:12 pm)
No thats whats so strange , I can see the explosion from the hit but "onCollision: does not get called.I put an echo into the "projectile::oncollision" function so that I can see if its getting called.
#3
01/02/2004 (9:50 am)
You'll have to put some debug statements in the C++ code, then to see what's happening...
#4
But i did find something out , I found that if I make the bounding box on the target player 5 units tall , It becomes apparent that the missing call only happens on the falling target when the projectile hits the top end of the bounding box.
If i hit the bottom of the box , it allways works
I suspect the oncollision check must be done slightly after the explosion ??
Ill be getting a compiler and will be starting to lern C++ after i get it.
Thanks for your help Ben.
Here is my simplified oncollision function i used for testing.
It just bounces the target up without dammage.
01/02/2004 (1:30 pm)
Im new to this , and cant read C++ or debug code yet ,, only script.But i did find something out , I found that if I make the bounding box on the target player 5 units tall , It becomes apparent that the missing call only happens on the falling target when the projectile hits the top end of the bounding box.
If i hit the bottom of the box , it allways works
I suspect the oncollision check must be done slightly after the explosion ??
Ill be getting a compiler and will be starting to lern C++ after i get it.
Thanks for your help Ben.
Here is my simplified oncollision function i used for testing.
It just bounces the target up without dammage.
function crossbowProjectile::onCollision(%this,%obj,%col,%fade,%pos,%normal)
{
%position = VectorAdd(%pos, VectorScale(%normal, 0.01));
%impulseVec = VectorSub(%col.getEyeTransform(), %position);
%impulseVec = VectorNormalize(%impulseVec);
%impulseVec = VectorScale(%impulseVec,6000);
%impulseVec = vectorAdd(%impulseVec,"0 0 3000");
%col.applyImpulse(%position, %impulseVec);
error("........................crossbowProjectile::onCollision called");
echo("%impulseVec applied = " @ %impulseVec);
}
#5
03/22/2004 (10:00 pm)
Brian, I have seen this problem, as well. I have several different types of objects...flying vehicles, wheeled vehicles, and player objects. With one (and so far only one) of my flying vehicles, occasionally (usually when the flying vehicle is moving toward me, but sometimes even when it's at rest) a projectile will explode when it hits the flying vehicle, but the onCollision handler is never fired. After tracing through the C++ code, I noticed that sometimes the client projectile will register a hit, while the server projectile does not. It will simply continue travelling until it expires, even though the client projectile exploded. Is there a reason why these things can get out-of-sync, and is there a work around for it? I'm a fairly advanced C++ coder and would sincerely appreciate any explanation of what might be happening. Thanks!
#6
Technically speaking onCollision should never be called on the client, since the client doesn't need to know anything from that really, unless you want it to.
If you want onCollision to be reliably called on client as well, in the ExplosionMask section of the unpackUpdate function call onCollision with the appropriate parameters right before they call explode in that same section.
The only reason onCollision is being called on the client side is, as I see it, a mistake in the bounce tick loop in processTick which is run both server and client side. So when this loop is executing on the client you see the onCollision calls for the bounce, but not for an actual collision(sometimes).
04/01/2004 (4:21 pm)
OnCollision will ALWAYS be called on the server. It is however, as you stated, unreliable on the client side.Technically speaking onCollision should never be called on the client, since the client doesn't need to know anything from that really, unless you want it to.
If you want onCollision to be reliably called on client as well, in the ExplosionMask section of the unpackUpdate function call onCollision with the appropriate parameters right before they call explode in that same section.
The only reason onCollision is being called on the client side is, as I see it, a mistake in the bounce tick loop in processTick which is run both server and client side. So when this loop is executing on the client you see the onCollision calls for the bounce, but not for an actual collision(sometimes).
#7
Its a fact of client/server life i think.
Bloody annoying though. Maybe sometime I'll get to the bottom of why it happens.
04/01/2004 (4:27 pm)
Ive had some weirdness with raycasts on the client side.. basically, sometimes they can just pass through things, sometimes they detect collisions that the server doesnt etc..Its a fact of client/server life i think.
Bloody annoying though. Maybe sometime I'll get to the bottom of why it happens.
#8
04/02/2004 (4:12 pm)
I just noticing that client side ray cast problem a couple of days ago myself. I've been implementing a new effects system and one of the affectors that you can apply is a collision check (that allows you to make particles or whatever that bounce off of things). It works fine for the most part, but some times it just won't register at all (or you'll get a really weird normal value) and the object will just keep on going.
#9
The problem I was seeing was where the client's onCollision was firing but not the server. In all these cases, it certainly looked like the projectile definitely hit the target. But, if there are no problems with server-side collision detection, then could it be because the target (in this case a FlyingVehicle) simply is in a slightly different position on the server, and therefore the projectile genuinely missed it? And if this is the case, should I just disable client side onCollision and let the server take care of it all? That way, I wouldn't get any visible projectile explosions that result in no damage to the target(or in damage to something behind the target). Does this sound reasonable? Again, thanks for everyone's responses!
04/05/2004 (7:59 am)
First of all, thanks to everyone for good responses.The problem I was seeing was where the client's onCollision was firing but not the server. In all these cases, it certainly looked like the projectile definitely hit the target. But, if there are no problems with server-side collision detection, then could it be because the target (in this case a FlyingVehicle) simply is in a slightly different position on the server, and therefore the projectile genuinely missed it? And if this is the case, should I just disable client side onCollision and let the server take care of it all? That way, I wouldn't get any visible projectile explosions that result in no damage to the target(or in damage to something behind the target). Does this sound reasonable? Again, thanks for everyone's responses!
#10
I've also noticed that the projectiles on the client dont always start exactly on the muzzle point.
Its difficult to describe but totally reproducable. Maybe i'll cap a video later.
05/03/2004 (7:02 am)
I've discovered a related problem with short range projectiles. If you make a projectile with a short lifetime it will go travel noticably farther on the client than it does on the server. But at the end of the range on the client the impacts are unreliable. I've also noticed that the projectiles on the client dont always start exactly on the muzzle point.
Its difficult to describe but totally reproducable. Maybe i'll cap a video later.
#11
VIDEO HERE
(2.21mb DivX 5.1.1 codec)
Here we have a spray can weapon that shoots paint projectiles. In the onCollision method of the paint projectile, it sets the skin of whatever it hits to red. Note that the projectiles hit even when i'm very far away, but the hit doesn't register until I'm very close. Looks like a prediction error.
05/03/2004 (9:28 am)
Ok here we go VIDEO HERE
(2.21mb DivX 5.1.1 codec)
Here we have a spray can weapon that shoots paint projectiles. In the onCollision method of the paint projectile, it sets the skin of whatever it hits to red. Note that the projectiles hit even when i'm very far away, but the hit doesn't register until I'm very close. Looks like a prediction error.
#13
Yeah Eric ive noticed that changeing start position also.
I dont know how to fix it yet but it sounds like Robert has made progress?
05/03/2004 (5:41 pm)
Groovy , legomod :)Yeah Eric ive noticed that changeing start position also.
I dont know how to fix it yet but it sounds like Robert has made progress?
#14
Notice also that I've said numerious times onCollision isn't meant for 'client side'
because it is not guaranteed. Only the explosion call is guaranteed, so tie any
of your client side effects off the explosion call and not onCollision.
I've added additional comments in the latest changes explaining why this is the case,
so check there first if you have any questions.
05/04/2004 (1:48 am)
Have you checked the latest projectile code to see if this wont solve your problems?Notice also that I've said numerious times onCollision isn't meant for 'client side'
because it is not guaranteed. Only the explosion call is guaranteed, so tie any
of your client side effects off the explosion call and not onCollision.
I've added additional comments in the latest changes explaining why this is the case,
so check there first if you have any questions.
#15
05/04/2004 (5:40 am)
I've found that the best solution for me was simply to disable the projectile's client side onCollision detection. The projectile still explodes when it actually hits something, and now I don't have any false explosions when only the client detects a hit. I haven't checked out the latest code yet, but I'll definitely take a look at it. For now, though, this seems to be an adequate solution.
#16
and that fixed the paint-going-too-far problem
05/04/2004 (12:43 pm)
I figured out one problem. The projectiles were relying on the server to tell them when to time out so they kept going during the time it took for the server to tell the client to kill the projectile. I just added this to projectile::processTickif(isGhost() && mCurrTick >= mDataBlock->lifetime)
mHidden = true;and that fixed the paint-going-too-far problem
#17
05/04/2004 (2:32 pm)
Thanks all, I will try it soon.
#18
I tested the latest version but that did not solve the problem , i still got explosions with no onCollision call,so I added a onExplode function to the starter.fps/server/scripts/crossbow.cs file and found that this call is also missing from the phantom explosion.
I did what Robert Howells recomended and that worked fine.
The down side is that sometimes it looks like the projectile gos through the player , but thats allot better than a false explosion so thanks allot Robert.
05/29/2004 (4:34 am)
Ok Thanks again , I just did some more tests and have solved my problem.I tested the latest version but that did not solve the problem , i still got explosions with no onCollision call,so I added a onExplode function to the starter.fps/server/scripts/crossbow.cs file and found that this call is also missing from the phantom explosion.
I did what Robert Howells recomended and that worked fine.
The down side is that sometimes it looks like the projectile gos through the player , but thats allot better than a false explosion so thanks allot Robert.
#19
onCollision only actually exists so it can call into server side scripts, as you can see... if you got the latest projectile code from HEAD.
05/29/2004 (9:32 am)
You guys don't seem to get the fact that onCollision is only supposed to ever be called or otherwise used on the SERVER.onCollision only actually exists so it can call into server side scripts, as you can see... if you got the latest projectile code from HEAD.
#20
In the starter.fps/server/scripts/crossbow.cs , onCollision is used to apply damage and radiusDamage right?
The problem is that sometimes the client will see an explosion that apparently does not do damage or radiusDamage.
The server detected a miss but the client detected a hit as you stated in the following quote from a post above.
"The only reason onCollision is being called on the client side is, as I see it, a mistake in the bounce tick loop in processTick which is run both server and client side. So when this loop is executing on the client you see the onCollision calls for the bounce, but not for an actual collision(sometimes)."
I think that mistake is what triggers the explosion on the client.
Thats why we had to disable the client side bounce tick loop in processTick.
In projectile.cc I put this-
if(isServerObject()){
just before the-
static U32 sMaxBounceCount = 5;
U32 bounceCount = 0;
while (bounceCount++ < sMaxBounceCount)
don't forget the } at the other end of the while loop.
Now the client projectile will not detect the hit and will not explode untill the server detects a hit.
Note ; I'm a noob so don't trust this code - It took me about 24 hrs + 10 compiles at 8 mins each to figure this one line out and im not sure if this may cause other problems. :)
05/29/2004 (5:58 pm)
I'm new so not 100% sure, but think i understand onCollision is only supposed to be called or used on the server.In the starter.fps/server/scripts/crossbow.cs , onCollision is used to apply damage and radiusDamage right?
The problem is that sometimes the client will see an explosion that apparently does not do damage or radiusDamage.
The server detected a miss but the client detected a hit as you stated in the following quote from a post above.
"The only reason onCollision is being called on the client side is, as I see it, a mistake in the bounce tick loop in processTick which is run both server and client side. So when this loop is executing on the client you see the onCollision calls for the bounce, but not for an actual collision(sometimes)."
I think that mistake is what triggers the explosion on the client.
Thats why we had to disable the client side bounce tick loop in processTick.
In projectile.cc I put this-
if(isServerObject()){
just before the-
static U32 sMaxBounceCount = 5;
U32 bounceCount = 0;
while (bounceCount++ < sMaxBounceCount)
don't forget the } at the other end of the while loop.
Now the client projectile will not detect the hit and will not explode untill the server detects a hit.
Note ; I'm a noob so don't trust this code - It took me about 24 hrs + 10 compiles at 8 mins each to figure this one line out and im not sure if this may cause other problems. :)
Associate Kyle Carter