PDA

View Full Version : Mesh does not collide with BSP brushes when moving it



jgg
04-06-2012, 06:56 PM
Hi all!

I have a simple object that my pawn must be able to grab, move, throw and release. Grabbing and throwing it seems to work properly, but when moving it collisions with brushes are somehow disabled. Note that collisions with other static meshes while moving it are working, but when the object is attached to my pawn (see code below) and I move around the level, which is built with BSP brushes, going through a door or getting close to a wall shows that the collision is not working although COLLIDE_BlockAll is specifically set by code. Next screenshot shows what I mean:

http://s14.postimage.org/yyfz82rq7/no_collision.png


Here is the code for the object (PSThrowableObject extends from KActor) and for the PlayerController:

Object:


class PSThrowableObjectContainer extends PSThrowableObject
placeable;

DefaultProperties
{
Begin Object class=StaticMeshComponent Name=PSThrowableObjectContainerMesh
StaticMesh=StaticMesh'PS_static_meshes.throwable.e nv_gen_container'
BlockActors=true
CollideActors=true
BlockRigidBody=true
BlockZeroExtent=true
HiddenGame=FALSE
HiddenEditor=FALSE
LightEnvironment=MyLightEnvironment
End Object
Mesh=PSThrowableObjectContainerMesh
Components.Add(PSThrowableObjectContainerMesh)

ThrowingMomentum=10000.0
}

PlayerController:


class PSPlayerController extends UDKPlayerController;

var PSThrowableObject ObjectCarrying;

// Camera zoom from console or key
exec function CameraZoom()
{
PSCamera(PlayerCamera).Zoom();
}

exec function StartFire( optional byte FireModeNum )
{
local PSGameInfo Game;
local Vector ThrowDirection;

if ( WorldInfo.Pauser == PlayerReplicationInfo )
{
SetPause( false );
return;
}

// If the player is not carrying anything, then start firing the current weapon
if ( Pawn != None && !bCinematicMode && !WorldInfo.bPlayersOnly && (ObjectCarrying == None) )
{
Pawn.StartFire(FireModeNum);
}
// If carrying an object, throw it!
else if ( Pawn != None && !bCinematicMode && !WorldInfo.bPlayersOnly && (ObjectCarrying != None) )
{
ObjectCarrying.SetPhysics(PHYS_RigidBody);
ObjectCarrying.SetCollisionType(COLLIDE_BlockAll);

ThrowDirection = Normal(vector(Rotation));
ObjectCarrying.StaticMeshComponent.AddImpulse(Thro wDirection * ObjectCarrying.GetThrowingMomentum());
ObjectCarrying.SetBase(None);

Game = PSGameInfo(WorldInfo.Game);
Game.SetSlowSpeed();

ObjectCarrying = None;
}
}

simulated function bool performedUseAction()
{
local Actor HitActor;
local vector OutLocation, HitLocation, HitNormal;
local rotator OutRotation;

OutLocation = Pawn.GetPawnViewLocation();
OutRotation = Pawn.GetViewRotation();

// Pawn already carrying an object --> release it
if( ObjectCarrying != None )
{
ObjectCarrying.SetPhysics(PHYS_RigidBody);
ObjectCarrying.SetCollisionType(COLLIDE_BlockAll);
ObjectCarrying.SetLocation(OutLocation + vect(30,0,0));
ObjectCarrying.SetBase(None);
ObjectCarrying = None;
return true;
}
// Pawn not carrying an object yet --> grab it
else
{
HitActor = Pawn.Trace(HitLocation, HitNormal, (OutLocation + vector(OutRotation) * 200), OutLocation, True);
ObjectCarrying = PSThrowableObject(HitActor);

// If the object trying to grab is a valid one, then grab it
if(ObjectCarrying != none)
{
ObjectCarrying.SetPhysics(PHYS_None);
ObjectCarrying.SetCollisionType(COLLIDE_BlockAll); // This doesn't avoid object collisions
// with brushes
ObjectCarrying.SetLocation(OutLocation + vect(0,0,80));
ObjectCarrying.SetBase(Pawn);
return true;
}
}

return super.PerformedUseAction();
}

DefaultProperties
{
CameraClass=class'PSGame.PSCamera'

ObjectCarrying=None
}



I've tried with many collision configuration variables, but they seem not to be related with the issue as they don't make any difference. I just want to move around with the object while preserving its collision interaction with both meshes (currently works) and brushes (not working when attached to the pawn). BTW, eventually the object should be attached to a socket in the pawn instead of using SetBase, so, has this any implication in the way collisions behave when moving with the object attached?


Thank so much for your help! =)

willyg302
04-07-2012, 09:22 PM
Well, you would still use SetBase() to attach to a socket. The socket name is just the fourth (optional) parameter of SetBase, and as far as I know it's the only way to attach actors to pawns (other than constraints).

My question is, why would you turn off Rigid Body physics when attaching to the pawn? Does it mess with how the pawn "holds" the object? Because using rigid body physics would be the ideal way to do what you're asking.

jgg
04-08-2012, 06:49 AM
Hi, willyg302. Thanks for your answer.

Regarding turning off Rigid Body physics, if I don't then the object doesn't move with the pawn, just stands at the same place although I can 'throw' it. I mean, I can not take the object and move it around with me although the rest of the code works. Do I need to add any other parameter setup?

BTW, when I build the map in the editor I get a warning that can be related with my issue:

PSThrowableObjectContainer_0: KActor has BlockRigidBody set to FALSE and no jonts

The weird thing here is that both in the actor properties and debugging I've checked that BlockRigidBody is actually set to TRUE, so I don't know why this warning error keeps appearing every time I build the map. Any idea?

willyg302
04-08-2012, 09:03 PM
I've heard of a few cases where people got the whole "rigid body to pawn" thing working, and the gist of it is, you want the pawn to move with the rigid body, not the other way around. Since you can simply use SetLocation() and SetRotation() to move/orient the pawn so that it appears to be attached to the kactor, which is something you can't do with a rigid body.

The error I think is because PHYS_None is enabled, the block rigid body is ignored so the engine "thinks" you have it disabled. But don't take my word for it.

jgg
04-09-2012, 05:12 PM
Do you mean that the PlayerController takes responsibility of the rigid body instead of the pawn?

Even if I comment the line where I set PHYS_None the warning keeps appearing, so it seems that has nothing to do with it.

I don't know what I'm doint wrong. Keeping collisions of for a moving rigid body can't be that difficult... U_U

willyg302
04-09-2012, 05:19 PM
Keeping collisions of for a moving rigid body can't be that difficult...

Haha you'd be surprised :p

But yes, you would control the rigid body and use AddForce() or AddImpulse() to move it around. The pawn would then update its location based on the location of the rigid body at any moment.

jgg
04-09-2012, 05:25 PM
In case this enabled/kept the rigid body collision, wouldn't that disable the pawn collision?

willyg302
04-09-2012, 05:36 PM
I just realized, that would be a real pain if you still wanted the pawn to retain its walking anims and such. Seems like more trouble than it's worth. But you wouldn't want to disable pawn collision since your pawn could then go through walls...and that would be bad.

jgg
04-09-2012, 05:38 PM
Yes, of course, I just was wondering if the problem I'm having now (pawn has collisions enabled; rigid body disabled) would be exchanged (rigid body has collisions enabled; pawn disabled!!).

willyg302
04-09-2012, 05:42 PM
Shouldn't be. As another thought, how do vehicles handle all this? Since vehicles like the hoverboard are basically rigid bodies (SVehicle) with a pawn based on them, and control is passed from the pawn to the vehicle upon DriverEnter().

VendorX
04-13-2012, 02:59 PM
ObjectCarrying.SetBase(Pawn); - this call is responsible for disabling collision.

jgg
04-13-2012, 03:07 PM
Thanks for your answer, VendorX. Do you know of any workaround for this issue? Or how should I implement the skill of moving objects around by attaching it to my pawn (the pawn is supposed to grab an object, then moving around, and eventually releasing or throwing it)?

AFAIK, weapons for example have no collision as they usually are 'inside' the pawn's collision cylinder. However, I've seen some videos where props can be moved around while keeping collisions enabled... So how to do it?

VendorX
04-13-2012, 03:19 PM
Not tested, but... First make sure, that attached actor do not collide with Pawn, then after SetBase try to re enable collision on attached actor. You can set Pawn as Owner in that actor too... The most important is what behavior you want to apply when collision will occur..?

jgg
04-13-2012, 03:38 PM
The Actor doesn't collide with the pawn, checked. I've tried reenabling collision after SetBase() and adding SetOwner(), but it doesn't work:



// Pawn not carrying an object yet --> grab it
else
{
HitActor = Pawn.Trace(HitLocation, HitNormal, (OutLocation + vector(OutRotation) * 200), OutLocation, True);
ObjectCarrying = PSThrowableObject(HitActor);

// If the object trying to grab is a valid one, then grab it
if(ObjectCarrying != none)
{
ObjectCarrying.SetPhysics(PHYS_None);
ObjectCarrying.SetCollisionType(COLLIDE_NoCollisio n);
ObjectCarrying.SetLocation(OutLocation + vect(0,0,80));
ObjectCarrying.SetBase(Pawn);
ObjectCarrying.SetOwner(Pawn);
ObjectCarrying.SetCollisionType(COLLIDE_BlockAll);

return true;
}
}


Regarding the behavior, I would like the collision to block the pawn, so the player needs to drop the object in order to walk through doors, for example.

VendorX
04-13-2012, 03:52 PM
Hmm... Tested - it work... Only problem is BSP...

TestPawn:


if( TestKActor(HitActor) != None)
{
HitActor.SetPhysics(PHYS_None);
HitActor.SetLocation(Location + Direction * 200);
HitActor.SetBase(Self);
HitActor.SetOwner(Self);
HitActor.SetCollisionType(COLLIDE_BlockAll);
}


TestKActo:


Begin Object Name=StaticMeshComponent0
StaticMesh=StaticMesh'ScriptTest_rc.StaticMeshes.S phereSM'
BlockNonZeroExtent=True
BlockZeroExtent=True
BlockActors=True
CollideActors=True
AlwaysCheckCollision=True
End Object

Touch will be called when collision occur - you can use it to detach from based Pawn.

jgg
04-13-2012, 06:58 PM
So, do you mean it does not work for BSPs? I've tried this code and still not working (for collisions with BSPs, which is what I'm trying to figure out... U_U)...

Ok, I've just read your answer in the other thread (to make KActors collide with BSPs blocking volumes are required). I tried before and it didn't work with my previous code. Let's see what happens now. However, does this means that I must generate blocking volumes for ALL BSPs in my map?

VendorX
04-13-2012, 07:03 PM
Yes... And don't forget to enable BlockRigidBody in each StaticMesh too.
I forgot to tell you about small problem - collision with SM or BSP wan't trigger events...

jgg
04-13-2012, 07:25 PM
Madness is in me... haha. I've set a blocking volume around a BSP, enabled the proper collision model for it and it still doesn't work.

http://s13.postimage.org/q9q2sgvb9/block_ed.png

http://s13.postimage.org/9n8ije2dh/block_game.png

VendorX, does this work for you? As you can see on previous code snippets, BlockRigidBody appears checked for my SM (in the editor as well). However, when I build the level I get this warning what I don't know how to fix and if it is somehow related to my issue:

KActor has BlockRigidBody set to FALSE and no joints.



class PSThrowableObjectContainer extends PSThrowableObject
placeable;

DefaultProperties
{
Begin Object Class=StaticMeshComponent Name=PSThrowableObjectContainerMesh
StaticMesh=StaticMesh'PS_static_meshes.throwable.e nv_gen_container'
BlockActors=true
CollideActors=true
BlockRigidBody=true
BlockZeroExtent=true
BlockNonZeroExtent=true
AlwaysCheckCollision=true
HiddenGame=FALSE
HiddenEditor=FALSE
LightEnvironment=MyLightEnvironment
End Object
Mesh=PSThrowableObjectContainerMesh
Components.Add(PSThrowableObjectContainerMesh)

ThrowingMomentum=10000.0
}



http://s11.postimage.org/fgnawi7i9/block_sm.png


What am I missing?

VendorX
04-13-2012, 07:33 PM
Add bCollideWorld=True and remove BlockRigidBody=true.

jgg
04-13-2012, 08:07 PM
NOW collision is working :) Thank you so much. When the Actor collides with the blocking volume it remains attached to the actor but is left behind ('colliding'). However, Touch() in my object class is not called, so I still can not detach it from my pawn (or stop the pawn) on collision detection.

PSThrowableObject (base class for all objects that can be thrown)



class PSThrowableObject extends KActor;

var StaticMeshComponent Mesh;

// Define how fast the object is thrown
var float ThrowingMomentum;

simulated event Touch(Actor other, PrimitiveComponent OtherComp, Vector HitLocation, Vector HitNormal) {
local PSPawn P;

P = PSPawn(other);

if (P != none) {
`log("The pawn is touching an object");
}

super.Touch(other,otherComp,hitLocation,hitNormal) ;
}

function float GetThrowingMomentum()
{
return ThrowingMomentum;
}

DefaultProperties
{
}



PSThrowableObjectContainer (the actual class I'm using for the container to be thrown)



class PSThrowableObjectContainer extends PSThrowableObject
placeable;

DefaultProperties
{
Begin Object Class=StaticMeshComponent Name=PSThrowableObjectContainerMesh
StaticMesh=StaticMesh'PS_static_meshes.throwable.e nv_gen_container'
BlockActors=true
CollideActors=true
BlockZeroExtent=true
BlockNonZeroExtent=true
AlwaysCheckCollision=true
HiddenGame=FALSE
HiddenEditor=FALSE
LightEnvironment=MyLightEnvironment
End Object
Mesh=PSThrowableObjectContainerMesh
Components.Add(PSThrowableObjectContainerMesh)

bCollideWorld=true

ThrowingMomentum=10000.0
}


Prior to all this collision issue I remember I got 'Touch' messages, so some of the changes I've been making to get collisions working must be messed the Touch function Oo. Any idea?

jgg
04-14-2012, 10:41 AM
Ok, I added a collision cylinder to the KActor and then the Touch() event works fine when colliding with my pawn, but Touch() is never called when colliding with the BlockingVolume as it is not an Actor nor a PrimitiveComponent.

So, which function/event do I need to override in KActor/Actor in order to block my pawn or detach the KActor from the based pawn?

jgg
04-16-2012, 06:25 PM
Does anybody know how to detect a collision between a KActor and a BlockingVolume?

willyg302
04-17-2012, 06:05 AM
event RigidBodyCollision(PrimitiveComponent HitComponent, PrimitiveComponent OtherComponent,
const out CollisionImpactData RigidCollisionData, int ContactIndex)
{
if(OtherComponent != none) {
if(BlockingVolume(OtherComponent.Owner) != none) {
// DO STUFF
}
}
super.RigidBodyCollision(HitComponent,OtherCompone nt,RigidCollisionData,ContactIndex);
}

Probably not the easiest way, but the most accurate for sure.

jgg
04-17-2012, 06:29 PM
Is this code for the KActor extender class? Because when my KActor collides with the BlockingVolume this event is never triggered...

meganaut
04-17-2012, 07:05 PM
just FYI, you can have the kActor in rigidbody mode, you just need to use the SetRBLocation and SetRBRotation methoeds rather than the normal methods.

-Mega