Game Development Community

T3D 1.1 Final - Some Ai Move Based Animation Fails (Poses) - CONFIRMED (THREED-1996)

by Steve Acaster · in Torque 3D Professional · 06/14/2011 (6:56 am) · 2 replies

T3D 1.1 Final

win7 32bit

target:
Ai move based (poses) animation, ai/player.cpp

issue:
When enabling multiple poses on AiPlayer (custom code see below), the Ai does not play the new pose animation when called. It does sometimes give a visible "judder" as though it's trying to play the animation. The bounding box and speed settings of the new pose update fine, but the stance/pose of the viewable model fails.

example:
Ai is standing, Ai gets command to move to crouch, Ai updates boundingBox and speed settings to "crouch mode" but does not play the animation for crouch or any crouch_move animations from there on.

When opening the World Editor the Ai suddenly updates their animation pose to the correct one.

Repeat:
First up, add some code to enable Ai to receive commands to change pose in a way that mimicks the player's direct input.
//aiplayer.cpp
bool AIPlayer::getAIMove(Move *movePtr)
{

//...

   // Replicate the trigger state into the move so that
   // triggers can be controlled from scripts.
   for( int i = 0; i < MaxTriggerKeys; i++ )
   {
      movePtr->trigger[i] = getImageTriggerState(i);

//yorks in start
	switch (mPose) 
	{
	   case StandPose:
		     movePtr->trigger[3] = false; 
			 movePtr->trigger[4] = false;
		break;
		case CrouchPose:				
			movePtr->trigger[3] = true; 
			movePtr->trigger[4] = false;
		 break;
		case PronePose:
			movePtr->trigger[3] = false;
			movePtr->trigger[4] = true;  
		 break;
	}
//yorks in end

   }

   mLastLocation = location;
   
   return true;
}

//yorks start
void AIPlayer::changePose(S32 poseNumber)
{
	Pose Pose = StandPose;
	if(poseNumber == 1) 
	{      
		Pose = CrouchPose;
	}
	else if(poseNumber == 2)
	{
		Pose = PronePose;
	}
	setPose(Pose);
}
//yorks end

//yorks start
ConsoleMethod( AIPlayer, setPose, void, 3, 3, "()"
			  "(int pose) StandPose=0,CrouchPose=1,PronePose=2")
{	
   object->changePose(dAtoi(argv[2]));
}//yorks end

//aiplayer.h
//...
   void stopMove();
   void changePose(S32 poseNumber);//yorks
};

#endif

And finally expose the stock "getPose" function to script.
//player.cpp
//yorks new
DefineEngineMethod( Player, getPose, S32, (),,
	"0=standPose, 1=crouchPose, 2=pronePose, 3=swimPosen" )
{  
   return object->getPose();  
}

Recompile, Open up a level in-game and get some AiPlayers in there. Give them names as it makes them easier to give commands from the console. In the console type:
aiName.setPose(1);
Watch nothing happen - though you may see a slight jitter on the model. Then type:
botname.getPose();
And the console will return the correct pose "1" or crouch_mode. Moving the bot about the Aiplayer will be moving at crouch_speed, just not playing the correct set of move animations.
//from player.cpp
pickBestMoveAction(PlayerData::CrouchRootAnim, PlayerData::CrouchRightAnim, &action, &forward);//Y U NO WORK!

Suggest:
Fix it!

I do have a workaround, which is to have the scripted function for calling the pose schedule a setTransform on the Ai's own getTransform 50m/s later. This kick starts the correct pose/move animations "most" of the time, still occaisionally fails.

example: (scripts/server/aiplayer.cs)
function AIPlayer::AiCrouch(%this)
{
   echo(%this.getname() @ " AiCrouch");
   %this.setPose(1);
   %this.schedule(50, "setTransform", %this.getTransform());
}


Note: possibly related to this issue - linky - when Ai who have been given an animation do not "snap" out of it when given a new move command (unlike the player does with direct input of a move command) as both issues work correctly with a player's direct input.



extra unrelated note:
I noticed that Ai still occaisionally glide - sometimes don't come out of their root animation on their first move (say to a node on a path), but often fix this on the move to their next.
I found that by delaying the ticktime for a new animation slightly seemed to fix this (but has had no effect on the above).
static const F32 sNewAnimationTickTime = 6.0f;//4 yorks
edit: ignore this last rambling bit - I forgot about occaisional issues with moving across flat terrain