About Store Forum Documentation Contact
Donations:
178$/mo



Post Reply 
How to protect NPCs from being pushed by a player?
Author Message
olej Offline
Member

Post: #1
How to protect NPCs from being pushed by a player?
Hi, I have a problem connected with the way PhysX deals with collision.

I've got two classes (Player and NPC) which derive from Chr class. While playing (using an instance of Player class of course) I am able to push other characters (NPCs) - they are moved because of the force of impact. I would like to remove this effect - NPCs are supposed to stand still / remain on their walking paths (they walk, so I cannot simply change them to statics) no matter what the player will try to do with them. I've tried following:
1. Increasing drastically the mass of NPC - dull solution, also the NPCs would slide down if the terrain is not perfectly flat.
2. Using PhysicsClass.dominance() method - doesn't seem to make any difference - according to [1][2] it cannot be helped.
3. Changing NPCs affiliation to Kinematic (Actor.kinematic()) but it as well does no difference.

I figured out that I can make my own function which will handle the collision of these two objects by using PhysicsClass.modifyContact() methods, but before I will proceed to doing this I would like to ask if there isn't any better solution? Some magical switch that would save my time? It's hard to believe that there is no such functionality.
05-04-2011 10:34 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #2
RE: How to protect NPCs from being pushed by a player?
kinematic should work ok, but for game::chr it's changed sometimes internally, you should override game::chr::enable/disable and after calling super adjust kinematic (just ideas)

you can also disable collisions physics.ignore
05-04-2011 10:36 PM
Find all posts by this user Quote this message in a reply
olej Offline
Member

Post: #3
RE: How to protect NPCs from being pushed by a player?
Thank you very much, overriding enable() did well smile

BTW, PhysicsClass.ignore() would completly disable collision handling so in that case Player would have been able to went straight through the NPC as if it was a ghost smile
05-04-2011 10:58 PM
Find all posts by this user Quote this message in a reply
dbuman Offline
Member

Post: #4
RE: How to protect NPCs from being pushed by a player?
If collision is semi-important, you can do like FFXI and set a timer for switching collision off.

when you collide with something, call: flt timer = Time.curTime();
when you create your character, set: int collide = 1;
this will act as a switch to tell the system you can collide with something
when you collide with someone (not sure of the way to detect this but when you find out, the rest is simple)
then use method:

if(Time.curTime() - timer >= 2)
{
Physics.ignore(Player1, Player2, True);
collide = 0;
Timer2 = Time.curTime();
}
if(collide == 0)
{if(Time.curTime() - timer2 >= 0.5)
{collide = 1;
Physics.ignore(Player1, Player2, False);
}}
(This post was last modified: 07-01-2011 03:06 AM by dbuman.)
07-01-2011 03:00 AM
Find all posts by this user Quote this message in a reply
Sadahar Offline
Member

Post: #5
RE: How to protect NPCs from being pushed by a player?
I have the same problem... Npcs are just pushed away... What do you mean with "Override enable"? I mean, what should the overriden code do? Is the kinematic state viable all the time? or should it just be used in "cut-scenes"? grin

Currently: setting kinematic to true -> does nothing.
"" "" .. and overriding enable/disable with blank block -> chrs cant move
setting mass to high value -> nothing.
(This post was last modified: 09-24-2011 06:23 PM by Sadahar.)
09-24-2011 06:01 PM
Find all posts by this user Quote this message in a reply
Fex Offline
Bronze Supporter

Post: #6
RE: How to protect NPCs from being pushed by a player?
Sorry to bump an old post, but I just came up with a way to accomplish this by setting they player's controller mass to a small value during collision with NPCs, then resetting it to the original value after there is no collision happening:

Put this in your Game Init() function:
Code:
Physics.reportContact(AG_AI, AG_CONTROLLER); // report contact so that player's mass can be reduced on contact with AI so AI doesn't slide.
   Physics.reportContact(ReportContact);

Put these where ever:

Code:
Flt originalmass;
Flt masschangedtimer = 0.0;

void ReportContact(ActorInfo &contact_a, ActorInfo &contact_b, C Vec &normal_force, C Vec &friction_force)
{
   Plr.ctrl.actor.mass(0.0001); Plr.masschangedtimer = Time.realTime();
   //CM.New(S+"Mass changed from "+Plr.originalmass+ " to "+Plr.ctrl.actor.mass() );
}

This where you create your player:
Code:
originalmass = T.ctrl.actor.mass();

This goes in your player update loop:
Code:
if(Plr.ctrl.actor.mass() != originalmass)if(Time.realTime()-masschangedtimer > 1.0)Plr.ctrl.actor.mass(originalmass);
02-12-2013 04:35 AM
Find all posts by this user Quote this message in a reply
Post Reply