Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I have a KActorSpawnable subclass that acts weird. In PostBeginPlay, I initialize an RB_ConstraintActor; the default is not to allow rotation. If I create one in the editor, it's fine, and won't rotate. If I spawn one, it rotates.

Here's the class:

class QuadForceKActor extends KActorSpawnable
    placeable;

var(Behavior) bool bConstrainRotation;
var(Behavior) bool bConstrainX;
var(Behavior) bool bConstrainY;
var(Behavior) bool bConstrainZ;

var RB_ConstraintActor PhysicsConstraintActor;

simulated event PostBeginPlay()
{
    Super.PostBeginPlay();

    PhysicsConstraintActor = Spawn(class'RB_ConstraintActorSpawnable', self, '', Location, rot(0, 0, 0));
    if(bConstrainRotation)
    {
        PhysicsConstraintActor.ConstraintSetup.bSwingLimited = true;
        PhysicsConstraintActor.ConstraintSetup.bTwistLimited = true;
    }
    SetLinearConstraints(bConstrainX, bConstrainY, bConstrainZ);

    PhysicsConstraintActor.InitConstraint(self, None);
}

function SetLinearConstraints(bool InConstrainX, bool InConstrainY, bool InConstrainZ)
{
    if(InConstrainX)
    {
        PhysicsConstraintActor.ConstraintSetup.LinearXSetup.bLimited = 1;
    }
    else
    {
        PhysicsConstraintActor.ConstraintSetup.LinearXSetup.bLimited = 0;
    }
    if(InConstrainY)
    {
        PhysicsConstraintActor.ConstraintSetup.LinearYSetup.bLimited = 1;
    }
    else
    {
        PhysicsConstraintActor.ConstraintSetup.LinearYSetup.bLimited = 0;
    }
    if(InConstrainZ)
    {
        PhysicsConstraintActor.ConstraintSetup.LinearZSetup.bLimited = 1;
    }
    else
    {
        PhysicsConstraintActor.ConstraintSetup.LinearZSetup.bLimited = 0;
    }
}

DefaultProperties
{
    bConstrainRotation=true
    bConstrainX=false
    bConstrainY=false
    bConstrainZ=false

    bSafeBaseIfAsleep=false
    bNoEncroachCheck=false
}

Here's the code I use to spawn one. It's a subclass of the one above, but it doesn't reference the constraint at all.

local QuadForceKCreateBlock BlockActor;

BlockActor = spawn(class'QuadForceKCreateBlock', none, 'PowerCreate_Block', BlockLocation(), m_PreparedRotation, , false);
BlockActor.SetDuration(m_BlockDuration);
BlockActor.StaticMeshComponent.SetNotifyRigidBodyCollision(true);
BlockActor.StaticMeshComponent.ScriptRigidBodyCollisionThreshold = 0.001;

BlockActor.StaticMeshComponent.SetStaticMesh(m_ValidCreationBlock.StaticMesh);
BlockActor.StaticMeshComponent.AddImpulse(m_InitialVelocity);

I used to initialize an RB_ConstraintActor where I spawned it from the outside. This worked, which is why I'm pretty sure it has nothing to do with the other code in QuadForceKCreateBlock.

I then added the internal constraint in QuadForceKActor for other purposes. When I realized I had two constraints on the CreateBlock doing the same thing, I removed the constraint code from the place where I spawn it. Then it started rotating.

Is there a reason I should not be initializing an RB_ConstraintActor in PostBeginPlay? I feel like there's some basic thing about how the engine works that I'm missing.

EDIT: I found roughly the same initialize code in Whizzle, the Psyonix game made purely with UDK for which the source is available: http://developer.download.nvidia.com/udk/Whizzle_Creation_Document_1_2.pdf

EDIT 2: The constraints are intialized by PostBeginPlay when loading the level, and that works for the placed objects. Just not for spawned objects.

share|improve this question
add comment

2 Answers

up vote 1 down vote accepted

This line

BlockActor.StaticMeshComponent.SetStaticMesh(m_ValidCreationBlock.StaticMesh);

Invalidates the constraint. Doing

BlockActor.StaticMeshComponent.SetStaticMesh(m_ValidCreationBlock.StaticMesh);
BlockActor.PhysicsConstraintActor.InitConstraint(BlockActor, none);

Fixes the issue.

share|improve this answer
add comment

I'm not sure of the order that things happen with KActors. It's possible that by PostBeginPlay() the KActor's physics haven't been fully initialized yet. As a test, you could try delaying creation of the constraint until the next Tick.

Alternatively, instead of spawning constraints you could try creating them in the defaultproperties section of your KActor. See UTVehicle_Hoverboard and its Content subclass for an example.

share|improve this answer
    
I will try messing with that. But I found almost exactly the same initialization in Psyonix's Whizzle source code. –  Almo Nov 9 '12 at 19:09
    
The Hoverboard initializes its constraints in PostInitRigidBody. I tried putting that function into my class, and it doesn't get called. –  Almo Nov 9 '12 at 19:19
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.