I had the same problem with implementing character movement with DarkA.I, because I was trying to get DP to move the character controller exactly X/Z where DarkA.i wanted it to go and I got very jerky movement and it didn't look very nice.
The other day I was wondering why my player char' controller moved so smoothly, then it hit me the reason it moves smoothly is because when I press 'w' to move forward I'm not trying to calculate an exact position to move to I'm just moving forward simple as that, then I thought well why can't I just do the same with DarkA.I controlled NPCs.
So what I ended up doing is forgetting the exact X/Z co-ords that the A.i wanted me to move to and just payed attention to which direction the A.I wanted me to move in and used the exact same code as I do for the player.
This is the first implementation of my npc team member movement code in my game:
` locals
Gravity as float : Gravity = lua get float( "g_gravity" )
Speed as float : Speed = lua get float( "g_speed" )
Action as string
Crouching as integer
Attacking as boolean = 0
Weapon as integer : Weapon = GetTeamMemberWeaponID( g_arrTeamMembers( CherIndex ) )
Accel as integer = 0
Strafe as integer = 0
` find out what the a.i system wants to do with this character
Action = ai get entity action$( CharID )
Crouching = ai get entity is ducking( CharID )
` stop the current anim
stop object CharID
` apply the correct animation to the member
select fast lower$( Action )
case "stopped"
` idle
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_idle_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_idle_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_idle_start" ), lua array int( "tblResistanceMainAnim->pistol_idle_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_idle_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_idle_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_idle_start" ), lua array int( "tblResistanceMainAnim->rifle_idle_end" ) : endif
endif
endcase
case "moving forwards"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_walk_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_walk_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_start" ), lua array int( "tblResistanceMainAnim->pistol_run_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_walk_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_walk_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_start" ), lua array int( "tblResistanceMainAnim->rifle_run_end" ) : endif
endif
` set the movement flag
Accel = 1
endcase
case "moving backwards"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_walk_backward_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_walk_backward_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_backward_start" ), lua array int( "tblResistanceMainAnim->pistol_run_backward_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_walk_backward_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_walk_backward_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_backward_start" ), lua array int( "tblResistanceMainAnim->rifle_run_backward_end" ) : endif
endif
` set the movement flag
Accel = -1
endcase
case "strafing left"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_left_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_left_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_left_start" ), lua array int( "tblResistanceMainAnim->pistol_run_left_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_left_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_left_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_left_start" ), lua array int( "tblResistanceMainAnim->rifle_run_left_end" ) : endif
endif
` set the strafe flag
Strafe = -1
endcase
case "strafing right"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_right_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_right_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_left_start" ), lua array int( "tblResistanceMainAnim->pistol_run_right_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_right_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_right_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_right_start" ), lua array int( "tblResistanceMainAnim->rifle_run_right_end" ): endif
endif
` set the strafe flag
Strafe = 1
endcase
case "stopped and attacking"
` idle attack
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_idle_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_idle_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_idle_start" ), lua array int( "tblResistanceMainAnim->pistol_idle_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_idle_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_idle_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_idle_start" ), lua array int( "tblResistanceMainAnim->rifle_idle_end" ) : endif
endif
` set the attacking flag
Attacking = 1
endcase
case "moving forwards and attacking"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_walk_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_walk_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_start" ), lua array int( "tblResistanceMainAnim->pistol_run_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_walk_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_walk_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_start" ), lua array int( "tblResistanceMainAnim->rifle_run_end" ): endif
endif
` set the attacking flag
Attacking = 1
` set the movement flag
Accel = 1
endcase
case "moving backwards and attacking"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_walk_backward_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_walk_backward_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_backward_start" ), lua array int( "tblResistanceMainAnim->pistol_run_backward_end" ): endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_walk_backward_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_walk_backward_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_backward_start" ), lua array int( "tblResistanceMainAnim->rifle_run_backward_end" ) : endif
endif
` set the attacking flag
Attacking = 1
` set the movement flag
Accel = -1
endcase
case "strafing left and attacking"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_left_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_left_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_left_start" ), lua array int( "tblResistanceMainAnim->pistol_run_left_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_left_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_left_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_left_start" ), lua array int( "tblResistanceMainAnim->rifle_run_left_end" ) : endif
endif
` set the attacking flag
Attacking = 1
` set the strafe flag
Strafe = -1
endcase
case "strafing right and attacking"
if Weapon = Pistol
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_right_start" ), lua array int( "tblResistanceMainAnim->pistol_crouch_strafe_right_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->pistol_run_left_start" ), lua array int( "tblResistanceMainAnim->pistol_run_right_end" ) : endif
else
if Crouching : loop object CharID, lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_right_start" ), lua array int( "tblResistanceMainAnim->rifle_crouch_strafe_right_end" )
else loop object CharId, lua array int( "tblResistanceMainAnim->rifle_run_right_start" ), lua array int( "tblResistanceMainAnim->rifle_run_right_end" ) : endif
endif
` set the attacking flag
Attacking = 1
` set the strafe flag
Strafe = 1
endcase
endselect
` rotate the object to the a.i angle
rotate object CharID, 0.0, ai get entity angle y( CharID ) , 0.0
` now apply graivity
phy set character controller displacement CharID, 0.0, Gravity
phy move character controller CharID, -1.0
` now apply movement, strafing takes presendence of forward backward movement
if Strafe <> 0
yrotate object CharID, object angle y( CharID ) + ( 90.0 * Strafe )
` now apply the movement
if Crouching : phy move character controller CharID, Speed
else : phy move character controller CharID, Speed * 1.8 : endif
` restore the original angle
yrotate object CharID, object angle y( CharID ) + ( 90.0 * -Strafe )
else : if Accel <> 0
` just apply movement
if Crouching : phy move character controller CharID, Speed * Accel
else : phy move character controller CharID, ( Speed * 1.8 ) * Accel : endif
endif : endif
` check if we are attacking
if Attacking
endif
You will notice that all I get from A.I is the direction it wants me to move in and then move it as normal and this works perfectly under manual mode, also (this is important) because I'm making a squad based game I need the equivalent of
ai entity follow player for manual mode, so logically I used
ai entity go to position and passed in the players position, and simply called this every loop to make the entity follow the player but this causes problems as the entity seems to dance around in circles and does all kinds of strange things, but if you just call it once then the entity moves normally to the position you specify.
The only way around this problem I have found so far is to create a path to the player from the entity then assign this path to the entity, this seems to result in smooth movement, but maybe you or somebody else knows of a better way?
Anyway hope this helps with the A.I thing.
I know the voices aren't real, but they have good ideas!