Results 1 to 6 of 6
  1. #1
    MSgt. Shooter Person
    Join Date
    May 2009
    Posts
    51

    Unhappy Various Ragdoll problems

    I want to have a ragdoll animation replicated over the network.
    I implemented a state to achieve that.

    Now, there are various problems that I so far failed to fix:

    If a client causes the ragdoll for another client (a server function is being called for that),
    it can see the ragdoll happening, but only when it was looking at the ragdolling pawn.
    If the pawn is not visible in the view, it just freezes in the ragdoll animation.
    I assume it is somehow related to the relevancy/rendering.

    Same situation: Sometimes the ragdoll animation is skipped and the pawn lays on the ground as
    if the ragdoll animation happened.. just that it didn't.. or that it was so fast that I couldn't see it.

    I am testing with several clients and a listening server.
    The server never shows any ragdoll animation. I have absolutely no idea why.


    This is the relevant code:

    Code:
    class DBPawn extends UTPawn;
    
    // Set in BeginState of state KnockedOut, used to tell other clients that this pawn is knockedout
    var repnotify bool bIsKnockedOut;
    
    // Called only if (Role == ROLE_Authority) 
    simulated function reduceHealth(int amount)
    {
    	if(bProtected)
    		return;
    
    	//TakeDamage(amount, kicker, Vect(0,0,0), 
    	Health = Max(0, Health-amount);
    	// Tell server about shake, needed to let charge fail
    	playHitEffect();
    	bSwitchHitEffect = !bSwitchHitEffect;
    	// Shake the client
    	//clientCamShake();
    
    	if(Health <= 0)
    	{
    		clientknockout();
    		GotoState('KnockedOut');
    	}
    }
    
    reliable client function ClientKnockOut()
    {
    	GotoState('KnockedOut');
    }
    
    
    state KnockedOut
    {
    	simulated event BeginState(name PreviousStateName)
    	{
    		if ( Role >= Role_AutonomousProxy )
    			PlayerController(Controller).bIgnoreMoveInput = 1;
    
    		bAlwaysRelevant=true;
    		bUpdateSimulatedPosition = true;
    		bNetDirty = true;;
    		bSkipAttachedMoves = false;
    
    		bIsKnockedOut = true;
    		EnableRagdoll();
    	}
    
    	simulated event EndKnockout ( )
    	{
    		bIsKnockedOut = false;
    		GotoState('auto');
    	}
    
    	simulated event EndState(name NextStateName)
    	{
    		bIsKnockedOut = false;
    		bAlwaysRelevant= false;
    
    		if ( Role >= Role_AutonomousProxy )
    			PlayerController(Controller).bIgnoreMoveInput = 0;
    
    		DisableRagdoll();		
    	}
    
    	simulated event Tick(float deltatime)
    	{
    		health = Min(100000, health + DeltaTime*1000);
    
    		if (health >= 5500)
    			gotoState('auto');
    	}
    
    	simulated function bool CalcCamera( float fDeltaTime, out vector out_CamLoc, out rotator out_CamRot, out float out_FOV )
    	{
    		local vector LookAt, x,y,z, ragdoll_pos;
    		local rotator ragdoll_rot;
    
    /*		out_CamRot = QuatToRotator(Mesh.GetBoneQuaternion('b_head'));
    		GetAxes(out_CamRot,x,y,z);
    		out_CamLoc = Mesh.GetBoneLocation('b_head') + z*10;
    */
    		CalcThirdPersonCam(fDeltaTime, out_CamLoc, out_CamRot, out_FOV);
    		return true;
    	}
    
    	simulated function EnableRagdoll()
    	{
    		local int i;
    		`log("Ragdoll: Role: "@Role);
    
    		Mesh.MinDistFactorForKinematicUpdate = 0;
    
    		//Mesh.SetTickGroup(TG_PostAsyncWork);
    
    		// ensure that the physics sub system instances the physics asset for this skeletal mesh.
    		`log("Hasphysics asset: "@Mesh.bHasPhysicsAssetInstance);
    
    		// Change collision component to skeletal mesh
    		CollisionComponent = Mesh;
    
    		// Disable cylinder collision
    		CylinderComponent.SetActorCollision(false, false);
    	
    		// ensures that the actor's location and rotation matches the root body's location and rotation
    		SetPhysics(PHYS_RigidBody);
    
    		// ensures that physics is blended in
    		Mesh.PhysicsWeight = 1.0;
    		Mesh.bEnableFullAnimWeightBodies = true;	
    
    		for(i=0; i<Mesh.PhysicsAsset.BodySetup.Length; i++)
    		{
    			Mesh.PhysicsAsset.BodySetup[i].bAlwaysFullAnimWeight = true;
    			Mesh.PhysicsAsset.BodySetup[i].bfixed = false;
    		}
    
    		// Unfix the rigid body instance so it is dynamic
    		Mesh.PhysicsAssetInstance.SetAllBodiesFixed(false);
    
    		// Set collision channel for Mesh so it doesn't fall through the world
    		Mesh.SetRBChannel(RBCC_Pawn);
    		Mesh.SetRBCollidesWithChannel(RBCC_Default, true);
    
    		// Ignore animation updates
    		Mesh.bUpdateKinematicBonesFromAnimation=FALSE;
    
    		// Update the skeleton even when we are not looking at it
    		Mesh.bUpdateSkelWhenNotRendered	= true;
    		Mesh.bIgnoreControllersWhenNotRendered = false;
    		Mesh.bTickAnimNodesWhenNotRendered = true;
    
    		// Sync RigidBody location with mesh collation		
    		Mesh.bSyncActorLocationToRootRigidBody = true;
    
    		// Force update the skel
    		Mesh.ForceSkelUpdate();
    		
    		SetMeshVisibility(true);
    
    		if (Mesh.bNotUpdatingKinematicDueToDistance)
    		{
    			Mesh.UpdateRBBonesFromSpaceBases(true, true);
    		}
    
    		// Disable collision with other actors
    		SetCollision(false, false, false);
    
    		// Set Velocity at the sceletal mesh
    		Mesh.SetRBLinearVelocity(Velocity, false);
    
    		// Wake the rigid body
    		Mesh.WakeRigidBody();
    	}
    
    	simulated function disableRagdoll ( )
    	{
    		Mesh.SetTickGroup(TG_PreAsyncWork);
    
    		// Enable collision
    		SetCollision(true, true, false);
    
    		// Enable cylinder collision
    		CylinderComponent.SetActorCollision(true, true);
    	
    		// Change collision component to cylinder
    		CollisionComponent = CylinderComponent;
    
    		// ensures that the actor's location and rotation matches the root body's location and rotation
    		SetPhysics(PHYS_Falling);
    
    		// Animation updates
    		Mesh.bUpdateKinematicBonesFromAnimation=true;
    
    		// Don't update when we are not looking at it
    		Mesh.bUpdateSkelWhenNotRendered	= false;
    		Mesh.bIgnoreControllersWhenNotRendered = true;
    		Mesh.bTickAnimNodesWhenNotRendered = false;
    
    		// Don't Sync RigidBody location with mesh collation		
    		Mesh.bSyncActorLocationToRootRigidBody = false;
    
    		// ensures that physics is blended in
    		Mesh.PhysicsWeight = 0.0;
    		Mesh.bEnableFullAnimWeightBodies = false;	
    
    		// Force update the skel
    		Mesh.ForceSkelUpdate();
    		
    		SetMeshVisibility(false);
    	}
    }
    
    simulated event ReplicatedEvent(name VarName)
    {
    	`log("Replication: " @ VarName);
    	switch(VarName)
    	{
    		case 'bIsKnockedOut':
    			if (bIsKnockedOut)
    				GotoState('KnockedOut');
    			else
    				GotoState('auto');
    			break;
    		default:
    			Super.ReplicatedEvent(VarName);
    			break;
    	}
    }
    
    replication
    {
    	if ( bNetDirty && Role == ROLE_Authority && RemoteRole == ROLE_SimulatedProxy )
    		bIsKnockedOut;
    }

  2. #2
    MSgt. Shooter Person
    Join Date
    May 2009
    Posts
    51

    Default

    This freezing is really weird. When it first happened, I thought it is maybe that the animation isn't updated anymore because it is for some reason no longer net-relevant.
    Then it dawned me that there might be a similar thing for rendering/visible, especially because there was basically the same thing when the mesh was invisible (I just wanted to orient the camera according to the head bone orientation/location). So the mesh animation wasn't updated when the mesh was hidden.
    Then I found

    Code:
    		Mesh.bUpdateSkelWhenNotRendered	= true;
    		Mesh.bIgnoreControllersWhenNotRendered = false;
    		Mesh.bTickAnimNodesWhenNotRendered = true;
    And thought that must be it! But it didn't change anything. Well. maybe it made it a tiny bit better, but it is a negligible difference.

    I also checked the bNotUpdatingKinematicDueToDistance variable in tick all the time, and it was never true. So it's not the distance either.

  3. #3
    MSgt. Shooter Person
    Join Date
    May 2009
    Posts
    51

    Default

    The freezing does not appear if I change the physics to PHYS_FALLING. But if I do that, the location of the actor is not in sync with the mesh. UAAH.

  4. #4
    Palace Guard

    Join Date
    Jun 2007
    Location
    Christchurch
    Posts
    3,514

    Default

    Remember that states also have simulated tags as well. It's plausible that the pawn on the client side is not entering the state you want it to be in.

  5. #5
    MSgt. Shooter Person
    Join Date
    May 2009
    Posts
    51

    Default

    Hmm Yes, my Knockout state had the simulated missing indeed. Didn't help my problem so far though :/
    Doing some more testing.

  6. #6
    MSgt. Shooter Person
    Join Date
    May 2009
    Posts
    51

    Default

    Okay, I could fix the freezing! Some other code was resetting the state to "PHYS_Falling" right after entering the knockout state! Took me ages to find this Oo


 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Copyright ©2009-2011 Epic Games, Inc. All Rights Reserved.
Digital Point modules: Sphinx-based search vBulletin skin by CompletevB.com.