Results 1 to 12 of 12
  1. #1
    MSgt. Shooter Person
    Join Date
    Oct 2011
    Posts
    36

    Default Changing States and Patrolling Bots

    Hello all,

    I'm currently having a problem with the States in my custom bot. My hope is the have the bot patrolling around, going from one path node to the next, until it sees the player. Once it sees the player, it switches over to the NavMesh for navigation. The NavMesh code is working perfectly fine, the problem I'm running into is having it patrol around on its own in the beginning. Here's the code I currently have:

    Code:
    /**
     *	PotatoChipController
     *
     *	Creation date: 27/02/2012 20:24
     *	Copyright 2012, Jay
     */
    class PotatoChipController extends AIController;
    
    var	Actor Player;
    
    var Vector TempDest;
    
    var float playerDistance;
    
    var int TimesShot;
    
    var int ChaseTimer;
    
    defaultproperties
    {
    }
    
    simulated event Possess(Pawn inPawn, bool bVehicleTransition)
    {
    	super.Possess(inPawn, bVehicleTransition);
    
    	// Important or bot will not move
    	Pawn.SetMovementPhysics();
    }
    
    // Starting State, watch for player
    auto state Idle
    {
    	
    	event SeePlayer (Pawn Seen)
    	{
    		`log("I SEE THE PLAYER");
    		// Call AIControllers SeePlayer function
    		super.SeePlayer(Seen);
    		Player = Seen;
    		TimesShot = 0;
    		ChaseTimer = 0;
    
    		// Get distance to player
    		playerDistance = VSize( Pawn.location - Player.location );
    
    		// If within 200 units start shooting at player, otherwise give chase
    		if( playerDistance < 200 )
    		{
    			GotoState('Shoot');
    		}
    		else
    		{
    			GotoState('Chase');
    		}
    	}
    	
    	Begin:
    		`log("Attempting to find Path Node at Start");
    		MoveTo(FindRandomDest().Location);
    }
    
    
    // Chases the player using direct movetoward if player is reachable and pathfinding if not
    state Chase
    {
    ignores SeePlayer;
    
    // Gets the navmesh path to the player
    function bool FindNavMeshPath()
    	{
    		// Clear cache and constraints (ignore recycling for the moment)
    		NavigationHandle.PathConstraintList = none;
    		NavigationHandle.PathGoalList = none;
    		NavigationHandle.bDebugConstraintsAndGoalEvals = true;
    		
    		// BAD DON'T USE UNTIL FIXED BY EPIC
    		//NavigationHandle.bUltraVerbosePathDebugging = true;
    
    		// Create constraints
    		class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Player );
    		class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Player, 25 );
    
    		// Find path
    		return NavigationHandle.FindPath();
    
    	}
    
    	Begin:
    		`log("BEGIN STATE CHASE");
    		Player = GetALocalPlayerController().Pawn;
    
    		// Check if the player is within firing range
    		playerDistance = VSize( Pawn.location - Player.location );
    
    		if(ChaseTimer > 0)
    		{
    			ChaseTimer -= 1;
    		}
    
    		// Give up if player is farther than 2000 units away
    		if( playerDistance > 2000 )
    		{
    			GotoState('Idle');
    		}
    		
    		// If player is between 400 and 1000 chase timer is equal to 0 start shooting
    		if( playerDistance > 400 && playerDistance < 1000 && ChaseTimer == 0)
    		{
    			//GotoState('Shoot');
    		}
    		// There is a direct path available to the player
    		if( NavigationHandle.ActorReachable( Player ) )
    			{
    				//FlushPersistentDebugLines();
    
    				/* 
    					The player is reachable so move towards him
    					Focus on the player
    					Offset destination by 100
    				*/
    				Pawn.StartFire(0);
    				
    				/*
    					COMMENT THIS TO INCREASE FIRING SPEED
    				*/
    				Pawn.StopFire(0);
    				
    				MoveToward( Player,Player, 100 );
    			}
    		// No direct path to player, use navmesh to find
    		else if( FindNavMeshPath() )
    			{
    				`log("FindNavMeshPath returned TRUE");
    				Pawn.StartFire(0);
    				
    				/*
    					COMMENT THIS TO INCREASE FIRING SPEED
    				*/
    				Pawn.StopFire(0);
    				
    				// The player is not reachable so use the navmesh path to move towards him
    				
    				// Set the ultimate destination to the players location
    				NavigationHandle.SetFinalDestination(Player.Location);
    				
    				// Debug info 
    				//FlushPersistentDebugLines();
    				//NavigationHandle.DrawPathCache(,TRUE);
    				//NavigationHandle.PrintPathCacheDebugText();
    				
    				/* 
    					TempDest is passed in by reference, is set to next location to move to
    					Stay outside of Pawns Collision Radius
    				*/
    				if( NavigationHandle.GetNextMoveLocation( TempDest, Pawn.GetCollisionRadius()) )
    				{
    					/*
    						Draws a line from the Pawns current location to the TempDest (proposed players location)
    						Draws a sphere at the proposed players location
    						Moves to destination
    					*/
    					//DrawDebugLine(Pawn.Location,TempDest,0,255,0,true);
    					//DrawDebugSphere(TempDest,16,20,0,255,0,true);
    					MoveTo( TempDest, Player );
    				}
    			}
    		else
    			{
    				// We can't get to the player so just go back to being Idle
    				MoveTo(FindRandomDest().Location);
    				`log("--------------------Attempting to find Path Node--------------------------");
    				//GotoState('IdleAgain');
    			}
    	goto 'Begin';
    }
    
    // Stop and fire at the player
    state Shoot
    {
    ignores SeePlayer;
    Begin:
    	Player = GetALocalPlayerController().Pawn;
    	
    	`log("OPEN FIRE");
    	
    	// Stop pawn from moving
    	Pawn.ZeroMovementVariables();
    	Sleep(1);
    	Pawn.StartFire(0);
    	
    	/*
    		COMMENT THIS TO INCREASE FIRING SPEED
    	*/
    	Pawn.StopFire(0);
    	
    	TimesShot += 1;
    
    	// If the player is too far away go back to Idle
    	playerDistance = VSize( Pawn.location - Player.location );
    
    	// If the player is too close, or too far too shoot, or we've shot 10 times already give chase again
    	if( playerDistance < 400 || playerDistance > 1000 || TimesShot > 10)
    	{
    		ChaseTimer = 5;
    		GotoState('Chase');
    	}
    	
    	goto 'Begin';
    }
    I've placed the log entries in the code to try and make sure that the code is being run. However, in the logs all I ever see are "BEGIN STATE CHASE" and "FindNavMeshPath returned TRUE." None of the others seem to be output to the log. I don't understand how that's possible if the rest of it runs as expected.
    Any help is appreciated as always. Here's some of the log:

    Code:
    [0015.18] ScriptLog: Player restarted
    [0015.18] ScriptLog: START MATCH
    [0015.18] Log: GFxMoviePlayer::Start called with no movie loaded
    [0015.18] ScriptWarning: Accessed None 'OnlineSub'
    	UDNPlayerController UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPlayerController_0
    	Function UTGame.UTPlayerController:ClientSetOnlineStatus:0033
    [0015.18] ScriptWarning: Accessed None 'OnlineSub'
    	UDNPlayerController UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPlayerController_0
    	Function UTGame.UTPlayerController:ClientSetOnlineStatus:02D1
    [0015.18] ScriptWarning: Accessed None
    	UDNPlayerController UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPlayerController_0
    	Function UTGame.UTPlayerController:ClientSetOnlineStatus:02E5
    [0015.18] Log: PIE: play in editor start time for UEDPIEUDN-GlowingLevel 0.272
    [0015.18] ScriptWarning: Player WhatToDoNext with no pawn
    	UTBot UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UTBot_0
    	Function UTGame.UTBot:WhatToDoNext:0068
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UTWeap_LinkGun UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UTWeap_LinkGun_0
    	Function UTGame.UTWeapon:SetupArmsAnim:004C
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UTWeap_LinkGun UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UTWeap_LinkGun_0
    	Function UTGame.UTWeapon:SetupArmsAnim:0160
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UTWeap_LinkGun UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UTWeap_LinkGun_0
    	Function UTGame.UTWeapon:SetupArmsAnim:0197
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UTWeap_LinkGun UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UTWeap_LinkGun_0
    	Function UTGame.UTWeapon:AttachWeaponTo:01AE
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UTWeap_LinkGun UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UTWeap_LinkGun_0
    	Function UTGame.UTWeapon:AttachWeaponTo:01E5
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:00B0
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:00EF
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:012E
    [0015.23] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:016D
    [0021.64] ScriptLog: BEGIN STATE CHASE
    [0022.59] ScriptLog: BEGIN STATE CHASE
    [0023.55] ScriptLog: BEGIN STATE CHASE
    [0024.50] ScriptLog: BEGIN STATE CHASE
    [0025.44] ScriptLog: BEGIN STATE CHASE
    [0026.40] ScriptLog: BEGIN STATE CHASE
    [0027.37] ScriptLog: BEGIN STATE CHASE
    [0028.32] ScriptLog: BEGIN STATE CHASE
    [0029.29] ScriptLog: BEGIN STATE CHASE
    [0030.24] ScriptLog: BEGIN STATE CHASE
    [0032.78] ScriptLog: BEGIN STATE CHASE
    [0033.72] ScriptLog: BEGIN STATE CHASE
    [0034.68] ScriptLog: BEGIN STATE CHASE
    [0035.64] ScriptLog: BEGIN STATE CHASE
    [0036.60] ScriptLog: BEGIN STATE CHASE
    [0038.37] ScriptLog: BEGIN STATE CHASE
    [0039.32] ScriptLog: BEGIN STATE CHASE
    [0040.28] ScriptLog: BEGIN STATE CHASE
    [0041.23] ScriptLog: BEGIN STATE CHASE
    [0042.19] ScriptLog: BEGIN STATE CHASE
    [0043.15] ScriptLog: BEGIN STATE CHASE
    [0043.49] ScriptWarning: Divide by zero
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function Engine.Pawn:TakeFallingDamage:0116
    [0048.89] ScriptLog: BEGIN STATE CHASE
    [0049.61] ScriptLog: BEGIN STATE CHASE
    [0049.63] ScriptLog: BEGIN STATE CHASE
    [0049.65] ScriptLog: BEGIN STATE CHASE
    [0049.67] ScriptLog: BEGIN STATE CHASE
    [0049.68] ScriptLog: BEGIN STATE CHASE
    [0049.70] ScriptLog: BEGIN STATE CHASE
    [0049.72] ScriptLog: BEGIN STATE CHASE
    [0049.74] ScriptLog: BEGIN STATE CHASE
    [0049.75] ScriptLog: BEGIN STATE CHASE
    [0049.77] ScriptLog: BEGIN STATE CHASE
    [0049.79] ScriptLog: BEGIN STATE CHASE
    [0049.81] ScriptLog: BEGIN STATE CHASE
    [0049.83] ScriptLog: BEGIN STATE CHASE
    [0050.99] ScriptLog: BEGIN STATE CHASE
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNWeap_RollingPin UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNWeap_RollingPin_0
    	Function UTGame.UTWeapon:SetupArmsAnim:004C
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNWeap_RollingPin UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNWeap_RollingPin_0
    	Function UTGame.UTWeapon:SetupArmsAnim:0160
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNWeap_RollingPin UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNWeap_RollingPin_0
    	Function UTGame.UTWeapon:SetupArmsAnim:0197
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNWeap_RollingPin UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNWeap_RollingPin_0
    	Function UTGame.UTWeapon:AttachWeaponTo:01AE
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNWeap_RollingPin UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNWeap_RollingPin_0
    	Function UTGame.UTWeapon:AttachWeaponTo:01E5
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:00B0
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:00EF
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:012E
    [0051.99] ScriptWarning: Accessed None 'ArmsMesh'
    	UDNPawn UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.UDNPawn_0
    	Function UTGame.UTPawn:WeaponChanged:016D
    [0052.15] ScriptLog: BEGIN STATE CHASE
    [0053.31] ScriptLog: BEGIN STATE CHASE
    [0053.31] Log: ------- PATH CONSTRAINT STATS --------
    [0053.31] Log: Processed: 75 ThrownOut: 0 (0.00% thrown out) AddedPathCost: 0.00 (0.00% total) AddedHeuristic: 417.00 (100.00% total) - (NavMeshPath_Toward_0)
    [0053.31] Log: --------------------------------------
    [0053.31] Log: TotalThrownOut: 0 TotalAddedDirectCost: 0.00 TotalAddedHeuristicCost: 417.00
    [0053.31] Log: ------- GOAL EVALUATOR STATS --------
    [0053.31] Log: Threw Out 22 (out of 23 processed (95.65%)) (Responsible for 100.00% of all nodes thrown out) - NavMeshGoal_At_0 
    [0053.31] Log: ---------------------------------------
    
    [0053.31] ScriptLog: FindNavMeshPath returned TRUE
    [0053.57] ScriptLog: BEGIN STATE CHASE
    [0053.57] Log: ------- PATH CONSTRAINT STATS --------
    [0053.57] Log: Processed: 92 ThrownOut: 0 (0.00% thrown out) AddedPathCost: 0.00 (0.00% total) AddedHeuristic: 392.00 (100.00% total) - (NavMeshPath_Toward_0)
    [0053.57] Log: --------------------------------------
    [0053.57] Log: TotalThrownOut: 0 TotalAddedDirectCost: 0.00 TotalAddedHeuristicCost: 392.00
    [0053.57] Log: ------- GOAL EVALUATOR STATS --------
    [0053.57] Log: Threw Out 26 (out of 27 processed (96.30%)) (Responsible for 100.00% of all nodes thrown out) - NavMeshGoal_At_0 
    [0053.57] Log: ---------------------------------------
    
    [0053.57] ScriptLog: FindNavMeshPath returned TRUE
    [0053.81] ScriptLog: BEGIN STATE CHASE

  2. #2
    MSgt. Shooter Person
    Join Date
    Aug 2010
    Location
    Australia
    Posts
    150

    Default

    Not sure why it's not working - but normally the default properties is put at the end of the code - it may cause problems where you have it.

  3. #3
    Banned
    Join Date
    Feb 2011
    Location
    BXL/Paris
    Posts
    2,169

    Default

    1. state Idle add goto 'Begin'; after MoveTo(FindRandomDest().Location);
    2. state Chase remove MoveTo(FindRandomDest().Location); and replace //GotoState('IdleAgain'); with GotoState('Idle');

  4. #4
    MSgt. Shooter Person
    Join Date
    Mar 2011
    Location
    Brisbane Australia
    Posts
    304

    Default

    I have a couple of suggestions.
    1- You should have logs in every possible execution path so you can tell what is happening.
    2- In your chase state yous hould probably put a small sleep between the startfire and stopfire functions.
    3- Personally I would use the whattodonext method, that way you can call LatentWhatToDoNext and wait for any latent executions to finish fully.

    -Mega

  5. #5
    MSgt. Shooter Person
    Join Date
    Oct 2011
    Posts
    36

    Default

    Thanks for the replies everyone. I moved the defaultproperties to the bottom, and added/changed the code in my states as Vendor suggested. Those seemed to change nothing at first, but then I went into Kismet and deleted the ActorFactory I had and remade it, changed the Factory from UTActorFactoryAI to just ActorFactoryAI and now it outputs to the log properly. I might try and do what you're suggesting meganaut and implement a whattodonext method, but once I've gotten the main functionality down.

    I'm still having problems trying to get the AI to randomly move between pathnodes in the beginning. As it is now, it seems to pick the same location every time, run to it and then stop until it see's the player. MoveTo(FindRandomDest().Location); should be finding the pathnodes and moving to a new one each pass if I'm not mistaken? Or is there a better way to do it?

    This is what's being output to the log now when it's trying to find a new location:

    Code:
    [1628.67] ScriptLog: Attempting to find Path Node at Start
    [1628.67] ScriptWarning: Accessed None
    	PotatoChipController UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.PotatoChipController_5
    	State UDNChefGame.PotatoChipController:Idle:0030
    [1628.69] ScriptLog: Attempting to find Path Node at Start
    [1628.69] ScriptWarning: Accessed None
    	PotatoChipController UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.PotatoChipController_5
    	State UDNChefGame.PotatoChipController:Idle:0030
    [1628.71] ScriptLog: Attempting to find Path Node at Start
    [1628.71] ScriptWarning: Accessed None
    	PotatoChipController UEDPIEUDN-GlowingLevel.TheWorld:PersistentLevel.PotatoChipController_5
    	State UDNChefGame.PotatoChipController:Idle:0030

  6. #6
    Banned
    Join Date
    Feb 2011
    Location
    BXL/Paris
    Posts
    2,169

    Default

    I don't know why, but sometimes i don't believe in what people saying. Have tested...

    (Your code + my changes)*2 test = it work

    Here is the code:
    Code:
    class PotatoChipController extends AIController;
    
    var	Actor Player;
    
    var Vector TempDest;
    
    var float playerDistance;
    
    var int TimesShot;
    
    var int ChaseTimer;
    
    simulated event Possess(Pawn inPawn, bool bVehicleTransition)
    {
    	super.Possess(inPawn, bVehicleTransition);
    
    	Pawn.SetMovementPhysics();
    }
    
    // Starting State, watch for player
    auto state Idle
    {
    
    	event SeePlayer (Pawn Seen)
    	{
    		`log("I SEE THE PLAYER");
    		// Call AIControllers SeePlayer function
    		super.SeePlayer(Seen);
    		Player = Seen;
    		TimesShot = 0;
    		ChaseTimer = 0;
    
    		// Get distance to player
    		playerDistance = VSize( Pawn.location - Player.location );
    
    		// If within 200 units start shooting at player, otherwise give chase
    		if( playerDistance < 200 )
    			GotoState('Shoot');
    		else
    			GotoState('Chase');
    	}
    
    	Begin:
    		`log("Attempting to find Path Node at Start");
    		MoveTo(FindRandomDest().Location);
    	goto 'Begin';
    }
    
    
    // Chases the player using direct movetoward if player is reachable and pathfinding if not
    state Chase
    {
    ignores SeePlayer;
    
    	// Gets the navmesh path to the player
    	function bool FindNavMeshPath()
    	{
    		// Clear cache and constraints (ignore recycling for the moment)
    		NavigationHandle.PathConstraintList = none;
    		NavigationHandle.PathGoalList = none;
    		NavigationHandle.bDebugConstraintsAndGoalEvals = true;
    
    		// BAD DON'T USE UNTIL FIXED BY EPIC
    		//NavigationHandle.bUltraVerbosePathDebugging = true;
    
    		// Create constraints
    		class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Player );
    		class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Player, 25 );
    
    		// Find path
    		return NavigationHandle.FindPath();
    	}
    
    	Begin:
    		`log("BEGIN STATE CHASE");
    		Player = GetALocalPlayerController().Pawn;
    
    		// Check if the player is within firing range
    		playerDistance = VSize( Pawn.location - Player.location );
    
    		if(ChaseTimer > 0)
    			ChaseTimer -= 1;
    
    		// Give up if player is farther than 2000 units away
    		if( playerDistance > 2000 )
    			GotoState('Idle');
    
    		// If player is between 400 and 1000 chase timer is equal to 0 start shooting
    		if( playerDistance > 400 && playerDistance < 1000 && ChaseTimer == 0)
    		{
    			//GotoState('Shoot');
    		}
    		// There is a direct path available to the player
    		if( NavigationHandle.ActorReachable( Player ) )
    		{
    			//FlushPersistentDebugLines();
    
    			/*
    				The player is reachable so move towards him
    				Focus on the player
    				Offset destination by 100
    			*/
    			Pawn.StartFire(0);
    
    			/*
    				COMMENT THIS TO INCREASE FIRING SPEED
    			*/
    			Pawn.StopFire(0);
    
    			MoveToward( Player,Player, 100 );
    		}
    		// No direct path to player, use navmesh to find
    		else if( FindNavMeshPath() )
    		{
    			`log("FindNavMeshPath returned TRUE");
    			Pawn.StartFire(0);
    
    			/*
    				COMMENT THIS TO INCREASE FIRING SPEED
    			*/
    			Pawn.StopFire(0);
    
    			// The player is not reachable so use the navmesh path to move towards him
    
    			// Set the ultimate destination to the players location
    			NavigationHandle.SetFinalDestination(Player.Location);
    
    			// Debug info
    			//FlushPersistentDebugLines();
    			//NavigationHandle.DrawPathCache(,TRUE);
    			//NavigationHandle.PrintPathCacheDebugText();
    
    			/*
    				TempDest is passed in by reference, is set to next location to move to
    				Stay outside of Pawns Collision Radius
    			*/
    			if( NavigationHandle.GetNextMoveLocation( TempDest, Pawn.GetCollisionRadius()) )
    			{
    				/*
    					Draws a line from the Pawns current location to the TempDest (proposed players location)
    					Draws a sphere at the proposed players location
    					Moves to destination
    				*/
    				//DrawDebugLine(Pawn.Location,TempDest,0,255,0,true);
    				//DrawDebugSphere(TempDest,16,20,0,255,0,true);
    				MoveTo( TempDest, Player );
    			}
    		}
    		else
    		{
    			// We can't get to the player so just go back to being Idle
    			//MoveTo(FindRandomDest().Location);
    			`log("--------------------Attempting to find Path Node--------------------------");
    			GotoState('Idle');
    		}
    
    	goto 'Begin';
    }
    
    // Stop and fire at the player
    state Shoot
    {
    ignores SeePlayer;
    Begin:
    	Player = GetALocalPlayerController().Pawn;
    
    	`log("OPEN FIRE");
    
    	// Stop pawn from moving
    	Pawn.ZeroMovementVariables();
    	Sleep(1);
    	Pawn.StartFire(0);
    
    	/*
    		COMMENT THIS TO INCREASE FIRING SPEED
    	*/
    	Pawn.StopFire(0);
    
    	TimesShot += 1;
    
    	// If the player is too far away go back to Idle
    	playerDistance = VSize( Pawn.location - Player.location );
    
    	// If the player is too close, or too far too shoot, or we've shot 10 times already give chase again
    	if( playerDistance < 400 || playerDistance > 1000 || TimesShot > 10)
    	{
    		ChaseTimer = 5;
    		GotoState('Chase');
    	}
    
    	goto 'Begin';
    }
    
    defaultproperties
    {
    	 bIsPlayer=true
    }
    BTW. Do some cleanup, because it's hard to find logic in this mess...
    Last edited by VendorX; 03-31-2012 at 04:28 AM.

  7. #7
    MSgt. Shooter Person
    Join Date
    Oct 2011
    Posts
    36

    Default

    The changes you suggested work in the sense that everything is now looping properly. The problem is that MoveTo(FindRandomDest().Location); isn't working as intended because according to the logs it's getting a NULL reference when executing that function. Which I find a little odd since it always manages to go to a specific spot each time and always goes back to that spot once it stops chasing me. In the editor there's nothing at the spot it goes to either, no pathnodes, no notes, the pylon for the navmesh doesn't originate from there either.

  8. #8
    Banned
    Join Date
    Feb 2011
    Location
    BXL/Paris
    Posts
    2,169

    Default

    Quote Originally Posted by Aerin41 View Post
    The changes you suggested work in the sense that everything is now looping properly. The problem is that MoveTo(FindRandomDest().Location); isn't working as intended because according to the logs it's getting a NULL reference when executing that function.
    In order to make FindRandomDest work you need some NavigationPoints in your level... When you don't have it, then it return "a NULL reference when executing that function."

    Quote Originally Posted by Aerin41 View Post
    Which I find a little odd since it always manages to go to a specific spot each time and always goes back to that spot once it stops chasing me. In the editor there's nothing at the spot it goes to either, no pathnodes, no notes, the pylon for the navmesh doesn't originate from there either.
    ...and that location is vect(0,0,0) - right?
    Last edited by VendorX; 03-31-2012 at 06:38 PM.

  9. #9
    MSgt. Shooter Person
    Join Date
    Oct 2011
    Posts
    36

    Default

    Yes, the location is vect(0,0,0). I have 4 pathnodes in there, the bot spawns from one of them.

  10. #10
    Banned
    Join Date
    Feb 2011
    Location
    BXL/Paris
    Posts
    2,169

    Default

    Quote Originally Posted by Aerin41 View Post
    Yes, the location is vect(0,0,0)...
    That's because engine can't find navigation network. In my test map i have +/-12 path nodes, weapon pickup etc. and it work perfectly - except state Shoot, which you need rewrite.

  11. #11
    MSgt. Shooter Person
    Join Date
    Oct 2011
    Posts
    36

    Default

    I actually got it to work in another way, let me know what you think. I tried to clean it up a bit.

    Code:
    class PotatoChipController extends AIController;
    
    var	Actor Player;
    var Vector TempDest;
    var float playerDistance;
    
    var int index;
    
    
    simulated event Possess(Pawn inPawn, bool bVehicleTransition)
    {
    	super.Possess(inPawn, bVehicleTransition);
    
    	// Important or bot will not move
    	Pawn.SetMovementPhysics();
    }
    
    
    
    // Starting State, watch for player
    auto state Idle
    {
    	
    	event SeePlayer (Pawn Seen)
    	{
    		`log("I SEE THE PLAYER");
    		// Call AIControllers SeePlayer function
    		super.SeePlayer(Seen);
    		Player = Seen;
    
    		// Get distance to player
    		playerDistance = VSize( Pawn.location - Player.location );
    
    		// If within 150 units start shooting at player, otherwise give chase
    		if( playerDistance < 150 )
    		{
    			GotoState('Shoot');
    		}
    		else
    		{
    			GotoState('Chase');
    		}
    	}
    	
    	Begin:
    		if(PotatoChipBag(Pawn) != None)
    		{	
    			// Move to the next destination on the list
    			MoveTo(PotatoChipBag(Pawn).PatDestination[index]);
    			
    			// If this isn't the end of the list
    			if(index < PotatoChipBag(Pawn).PatDestination.length - 1)
    			{
    				// Go to next node
    				index++;
    			}
    			else
    			{
    				// Return to beginning node
    				index = 0;
    			}
    		}
    	goto 'Begin';
    }
    
    
    // Chases the player using direct movetoward if player is reachable and pathfinding if not
    state Chase
    {
    	ignores SeePlayer;
    
    	// Gets the navmesh path to the player
    	function bool FindNavMeshPath()
    	{
    		// Clear cache and constraints (ignore recycling for the moment)
    		NavigationHandle.PathConstraintList = none;
    		NavigationHandle.PathGoalList = none;
    		NavigationHandle.bDebugConstraintsAndGoalEvals = true;
    
    		// Create constraints
    		class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle, Player );
    		class'NavMeshGoal_At'.static.AtActor( NavigationHandle, Player, 25 );
    
    		// Find path
    		return NavigationHandle.FindPath();
    
    	}
    
    	Begin:
    		`log("BEGIN STATE CHASE");
    		Player = GetALocalPlayerController().Pawn;
    
    		// Check if the player is within firing range
    		playerDistance = VSize( Pawn.location - Player.location );
    
    		// Give up if player is farther than 2000 units away
    		if( playerDistance > 2000 )
    		{
    			`log("PLAYER IS TOO FAR AWAY, GOING BACK TO PATROLLING STATE");
    			GotoState('Idle');
    		}
    		
    		// If player is between 400 and 1000 chase timer is equal to 0 start shooting
    		if( playerDistance < 150)
    		{
    			`log("PLAYER IS CLOSE ENOUGH TO BE ATTACKED");
    			GotoState('Shoot');
    		}
    		// There is a direct path available to the player
    		if( NavigationHandle.ActorReachable( Player ) )
    		{
    			/* 
    				The player is reachable so move towards him
    				Focus on the player
    				Offset destination by 100
    			*/				
    			`log("PLAYER IS REACHABLE");
    			MoveToward( Player,Player, 100 );
    		}
    		// No direct path to player, use navmesh to find
    		else if( FindNavMeshPath() )
    		{
    			`log("FindNavMeshPath returned TRUE");
    			
    			// Set the ultimate destination to the players location
    			NavigationHandle.SetFinalDestination(Player.Location);
    			
    			/* 
    				TempDest is passed in by reference, is set to next location to move to
    				Stay outside of Pawns Collision Radius
    			*/
    			if( NavigationHandle.GetNextMoveLocation( TempDest, Pawn.GetCollisionRadius()) )
    			{
    				`log("MOVING TOWARD PLAYER");
    				MoveTo( TempDest, Player );
    			}
    		}
    		else
    		{
    			// We can't get to the player so just go back to being Idle
    			`log("UNABLE TO FIND PATH TO PLAYER VIA NAVIGATION MESH");
    			GotoState('Idle');
    		}
    		goto 'Begin';
    }
    
    // Stop and fire at the player
    state Shoot
    {
    	ignores SeePlayer;
    	Begin:
    		Player = GetALocalPlayerController().Pawn;
    		
    		`log("OPEN FIRE");
    		
    		// Stop pawn from moving
    		Pawn.ZeroMovementVariables();
    		Sleep(1);
    		Pawn.StartFire(0);
    		Pawn.StopFire(0);
    		
    		playerDistance = VSize( Pawn.location - Player.location );
    
    		// If the player is too far away
    		if(playerDistance > 150)
    		{
    			GotoState('Chase');
    		}
    		
    		goto 'Begin';
    }
    
    defaultproperties
    {
    	index = 0;
    }
    The way it works now is the pawn has an array of vectors as one of its properties which is able to be added to from the editor. This way I can control where it goes. The only problem I have left is that it doesn't seem to register the Touch event with the player, but it does with the InterpActors I have in my level. Any ideas what might be wrong?

    Code:
    class PotatoChipBag extends UDKPawn
            placeable
    	ClassGroup( ChefGameActors );
    
    var() array<Vector> PatDestination;
    
    event Touch(Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal)
    {
       local Pawn pawnLocal;
       
       pawnLocal = Pawn( Other ); 
       
       `log("----------TOUCHED SOMETHING----------");
       if(pawnLocal != None)
       {
            //test if it is the Player
          if( pawnLocal.controller.bIsPlayer ) 
          {
    		`log("----------TOUCHED THE PLAYER----------");
             pawnLocal.HealthMax -= 50;
             pawnLocal.Health = pawnLocal.HealthMax;
             
             //'self' is a reference to the current object (UltraHealthPack)
             //self.Destroy();
          }
       }
    }  
    
    defaultproperties
    {
        Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
    		bSynthesizeSHLight=TRUE
    		bIsCharacterLightEnvironment=TRUE
    		bUseBooleanEnvironmentShadowing=FALSE
    		InvisibleUpdateTime=1
    		MinTimeBetweenFullUpdates=.2
    	End Object
    	Components.Add(MyLightEnvironment)
    	
    	
    	// Use collision cylinder to be used for navigation
    	Begin Object Name=CollisionCylinder
    		CollisionRadius=+0021.000000
    		CollisionHeight=+44.000000
    	End Object
    	CylinderComponent=CollisionCylinder
    
    	// Set the mesh to be a default
    	Begin Object Class=SkeletalmeshComponent Name=AttackPawnSkeletalMesh
    		LightEnvironment=MyLightEnvironment
    		BlockRigidBody=true;
    		CollideActors=true;
    		SkeletalMesh=SkeletalMesh'Chip_Model.Skeletal_Meshes.Chip_Model'
    		PhysicsAsset=PhysicsAsset'Chip_Model.All_Sets.Chip_PhysicsSet'
    		AnimSets(0)=AnimSet'Chip_Model.All_Sets.Chip_AnimSet'
    		AnimtreeTemplate=AnimTree'Chip_Model.All_Sets.Chip_AnimTree'
    	End Object
    	Mesh=AttackPawnSkeletalMesh
    
    	// Important
    	Components.Add(AttackPawnSkeletalMesh)
    	
    	ArmsMesh[0]=None	
    	ArmsMesh[1]=None
    	
    	PatDestination[0]=vect(0,0,0)
    
    	// Use our AttackAI Controller
    	ControllerClass=class'UDNChefGame.PotatoChipController'
    	
    
    	// set some movement parameters
    	bJumpCapable=false
    	bCanJump=false
    	GroundSpeed=300.0
    	MaxStepHeight = 50.0
        
    }

  12. #12
    MSgt. Shooter Person
    Join Date
    Oct 2011
    Posts
    36

    Default

    Think I got it, I didn't realize there was a Bump function for use with Pawns. Is there a way to detect when the collision ends? There are PostTouch and UnTouch functions, but those don't work for the same reason Touch didn't work. I ask because it keeps on registering the collision which is a problem since I would like to decrement the player's health upon touch. If that touch keeps happening every loop then his health drops to 0 in a second.


 

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.