Game Development Community

AI for fps needed

by Jaafer · in Torque 3D Beginner · 10/10/2009 (11:06 am) · 23 replies

Im using torque 3d 1.0 and im having a problem with AI, could someone please give me a full AI for fps.I am not making this game to sell i am only 16 i am gonna start university real soon (game development) and i live in Sudan so i cant really license it :D i am just learning on my own .i am a beginner programmer and 3d designer (I know the basics)and a master of photoshop and all i need is a simple AI that spawns an enemy ,makes him walk around and shoot when he "sees" the player, that's all.please.and thanks for the quick reply.

About the author

Recent Threads

Page «Previous 1 2
#1
10/10/2009 (11:22 am)
best AI requires to do changes to the source code, for that you'll need to purchase a licence...
#2
10/10/2009 (12:15 pm)
How are you using Torque 3D without owning it Jade ?
#3
10/10/2009 (1:18 pm)
@Matt
Demo

"Full" AI is some pretty big work and very gameplay specific, even between games of the same genre.
#4
10/10/2009 (1:50 pm)
@Jade: I'm available for contract work. Email me with complete details of your needs if you would like a bid.
#5
10/11/2009 (4:50 pm)
please just any tutorial for basic torque 3d AI
#6
10/12/2009 (11:25 pm)
Here's some Torque Script for you to use/look at. This is the *really basic* AI that we've been using in ZDay up until now for the zombies. It's a modified version of the AIPlayer script that came with TGE, and it works in TGEA so I assume it will probably work in T3D.

Basically you need to make a bunch of paths (must be a loop) that the bots can run around.

When the bots spawn they are placed on a random path and run around that path until they spot a player, then they will chase that player. If the lose sight of the player they will run to where the player was last seen and then then they will return to the closest path node and follow the path that the node is on.

Our zombies are unarmed but the script can be easily modified so that the bots shoot when the see a player.

There are 3 scripts:

- spawning code
- code attached to bot datablock
- thinking code


(Due to the word limit I'll have to post the code separately and in many pieces... code follows)
#7
10/12/2009 (11:29 pm)
Spawning Code
// ---------------------------------------------
// This controls the spawning and re-spawning of zombies
// AKA: zombie spawn manager
// ------------------------------------------------


$ZOMBIE_SPAWN::COUNT = 0;														// number of zombies we have (start at 0!)
$ZOMBIE_SPAWN::MAX_ZOMBIES = 20;												// max zombies
$ZOMBIE_SPAWN::PATH_COUNT = 20;
$ZOMBIE_SPAWN::PATHS[0] = "containerYard2";
$ZOMBIE_SPAWN::PATHS[1] = "containerYard1";
$ZOMBIE_SPAWN::PATHS[2] = "containerYard3";
$ZOMBIE_SPAWN::PATHS[3] = "warehouseGroup1_1";
$ZOMBIE_SPAWN::PATHS[4] = "warehouseGroup1_2";
$ZOMBIE_SPAWN::PATHS[5] = "warehouseGroup1_3";
$ZOMBIE_SPAWN::PATHS[6] = "groundFloorFlats";
$ZOMBIE_SPAWN::PATHS[7] = "townHouses1Path";
$ZOMBIE_SPAWN::PATHS[8] = "laneway1path";
$ZOMBIE_SPAWN::PATHS[9] = "townHouses3Path";
$ZOMBIE_SPAWN::PATHS[10] = "townhouses4Path";
$ZOMBIE_SPAWN::PATHS[11] = "townhouses5Path";
$ZOMBIE_SPAWN::PATHS[12] = "flats1path";
$ZOMBIE_SPAWN::PATHS[13] = "flats2path";
$ZOMBIE_SPAWN::PATHS[14] = "sewerPath1";
$ZOMBIE_SPAWN::PATHS[15] = "flats2path";
$ZOMBIE_SPAWN::PATHS[16] = "retailBuilding1Path";
$ZOMBIE_SPAWN::PATHS[17] = "parkPath1";
$ZOMBIE_SPAWN::PATHS[18] = "perimeter1path";
$ZOMBIE_SPAWN::PATHS[19] = "retailBuilding1Path2";




$ZOMBIE_SPAWN::THINK_PERIOD_MIN = 500;				// time between thoughts
$ZOMBIE_SPAWN::THINK_PERIOD_MAX = 1337;				// time between thoughts (ha - not so 1337)
$ZOMBIE_SPAWN::ATTACK_RANGE = 1.5;				// max range for melee attack
$ZOMBIE_ATTACK_DAMAGE = 9;
$ZOMBIE_SPAWN::VIEW_RADIUS = 1.05;				// 60 deg each side so 120Deg
$ZOMBIE_SPAWN::VIEW_DIST = 45;						// will spot targets up to 100m away
$ZOMBIE_SPAWN::SWAP_TARGET_RATIO = 0.5;		// ratio of distances to swap target (ie. .5 means new target must 50% closer to swap, .3 = 30%
$ZOMBIE_SPAWN::RESPAWN_TIME = 5000;          // time till respawn

if (true)  // play game (ie give me bots)
{
   $ZOMBIE_SPAWN::THINK = true;                // true if zombies are to think
   $ZOMBIE_SPAWN::RESPAWN_ON_DEATH = true;     // true if zombies are to respawn after death
   $ZOMBIE_SPAWN::SPAWN_ALL_ZOMBIES = true;    // spawn zombies at start up
   $ZOMBIE_SPAWN::SPAWN_TEST_ZOMBIE = false;    // spawn test zombie at start up
}
else  // test zombies
{
   $ZOMBIE_SPAWN::THINK = false;                // true if zombies are to think
   $ZOMBIE_SPAWN::RESPAWN_ON_DEATH = false;     // true if zombies are to respawn after death
   $ZOMBIE_SPAWN::SPAWN_ALL_ZOMBIES = false;    // spawn zombies at start up
   $ZOMBIE_SPAWN::SPAWN_TEST_ZOMBIE = false;    // spawn test zombie at start up
}
// ------------------------------
// creates the initial zombies
function createInitialZombies()
{
	echo("c6Creating Zombie", $ZOMBIE_SPAWN::COUNT);
	%path = $ZOMBIE_SPAWN::PATHS[getRandom(0, $ZOMBIE_SPAWN::PATH_COUNT - 1)];
	spawnZombieOnPath(%path);
	$ZOMBIE_SPAWN::COUNT++;
	
	// we only want 20 zombies created 10 sec apart
	if ($ZOMBIE_SPAWN::COUNT < $ZOMBIE_SPAWN::MAX_ZOMBIES)	
		schedule(10000, 0, "createInitialZombies");
}

(spawning code continues...)
#8
10/12/2009 (11:31 pm)
(Damn.. who put all these limits on posting on the GG website ?!?
... waiting ...waiting)

Spawning code continued

// -----------------------------------
function createTestZombie()
{
	echo("c6Creating Test Zombie");
	%zombie = spawnZombie();
	%zombie.setName("Bob");
}

// -----------------------------------
// this spawns a zombie
// ACCEPTS: spawn point (transform) (0 or "" to pick from spawn points)
// RETURNS: zombie obj
function spawnZombie(%spawn_point)
{
	if (%spawn_point == 0 || %spawn_point $= "")
		%spawn_point = pickZombieSpawnPoint(); 
	
	// Create the demo player object
  %player = new AIPlayer() 
	{
		dataBlock = Zombie1Body;
		path = "";
	};
	 
	MissionCleanup.add(%player);
	%player.setTransform(%spawn_point);  
	%player.targetCount = 0;   
	%player.is_bot = true;
	
	%player.think_period = getRandom($ZOMBIE_SPAWN::THINK_PERIOD_MIN, $ZOMBIE_SPAWN::THINK_PERIOD_MAX);
	
	if ($ZOMBIE_SPAWN::THINK == true)
	   %player.schedule(%this.think_period, "think"); 
	   
	return %player;
}




//----------------------------------------------------------------------------
// ACCEPTS: path object 
// RETURNS: AIPlayer object with a zombie datablock
function spawnZombieOnPath(%path)
{
	// Spawn a player and place him on the first node of the path
	if (!isObject(%path))
		return 0;
	%node = %path.getObject(0);
	%player = spawnZombie(%node.getTransform());
	
	// make him follow the path
	// and start thought process
	if (isObject(%player))
	{
		%player.followPath(%path, -1);
		
		if ($ZOMBIE_SPAWN::THINK == true)
		   %player.schedule($ZOMBIE_SPAWN::THINK_PERIOD, "think"); 
	}
		
	%player.last_action = "FOLLOW_PATH";	
	echo("c6Spawning zombie on path=", %path, " ID=", %player);
	return %player;
}

// ----------------------------------------------
// RETURNS: a random zombie spawn point
function pickZombieSpawnPoint()
{
	%groupName = "MissionGroup/ZombieDropPoints";
	%group = nameToID(%groupName);
	
	if (%group != -1) {
		%count = %group.getCount();
		if (%count != 0) {
			 %index = getRandom(%count-1);
			 %spawn = %group.getObject(%index);
			 return %spawn.getTransform();
		}
		else
			 error("No spawn points found in " @ %groupName);
	}
	else
		error("Missing spawn points group " @ %groupName);
	
	// Could be no spawn points, in which case we'll stick the
	// Zombie at the center of the world.
	return "0 0 300 1 0 0 0";
}
#9
10/12/2009 (11:32 pm)
Attached to the enemy Datablock
//-----------------------------------------------------------------------------
// Data for Zombie 1.
//-----------------------------------------------------------------------------




// Load dts shapes and merge animations
exec("~/data/shapes/adam/zombie.cs");

//----------------------------------------------------------------------------
// Zombie Datablock
// Define Zombie1
datablock PlayerData(Zombie1Body : PlayerBody)
{ 
	 shapeFile = "~/data/shapes/adam/player.dts";
	 boundingBox = "0.7 0.9 1.7";	// for Adam

   // NOTE: doesn't pick up anything - so no inventory items
	 // Carried items is handled elsewhere and they only spawn when the zombie dies
	 maxInv = "";
};


// -----------------------------------
function Zombie1Body::onReachDestination(%this,%obj)
{
   // Moves to the next node on the path.
   // Override for all player. Normally we'd override this for only
   // a specific player datablock or class of players.
   if (%obj.path !$= "") 
   {
      if (%obj.currentNode == %obj.targetNode)
         %this.onEndOfPath(%obj,%obj.path);
      else
         %obj.moveToNextNode();
   }
}

// -----------------------------------
function Zombie1Body::onEndOfPath(%this,%obj,%path)
{
   %obj.nextTask();
}

// -----------------------------------
function Zombie1Body::onEndSequence(%this,%obj,%slot)
{
   echo("Sequence Done!");
   %obj.stopThread(%slot);
   %obj.nextTask();
}
#10
10/12/2009 (11:34 pm)
This is the code that makes the bot think
//-----------------------------------------------------------------------------
// Torque Game Engine 
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------



//-----------------------------------------------------------------------------
// AIPlayer methods 
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// ACCEPTS: path obj, node index
function AIPlayer::followPath(%this,%path,%node)
{
   // Start the player following a path
   %this.stopThread(0);
   if (!isObject(%path)) {
      %this.path = "";
      return;
   }
  
   // not using target nodes as we want the bot to run
   // continuously around the path
 //  if (%node > %path.getCount() - 1)
 //     %this.targetNode = %path.getCount() - 1;
 //  else
      %this.targetNode = -1;
      
      
   if (%this.path $= %path)
      %this.moveToNode(%this.currentNode);
   else 
	 {
      %this.path = %path;
      
      // if node is not valid (ie.-1) go to the first node      
      if (%node < 0 || %node > %path.getCount() - 1)
         %this.moveToNode(0);
      else
         %this.moveToNode(%node); 
   }
}

//-----------------------------------------------------------------------------
function AIPlayer::moveToNextNode(%this)
{
   if (%this.targetNode < 0 || %this.currentNode < %this.targetNode) {
      if (%this.currentNode < %this.path.getCount() - 1)
         %this.moveToNode(%this.currentNode + 1);
      else
         %this.moveToNode(0);
   }
   else
	 {
      if (%this.currentNode == 0)
         %this.moveToNode(%this.path.getCount() - 1);
      else
         %this.moveToNode(%this.currentNode - 1);
	}
}
//-----------------------------------------------------------------------------
function AIPlayer::moveToNode(%this,%index)
{
   // Move to the given path node index
   %this.currentNode = %index;
   %node = %this.path.getObject(%index);
   %this.setMoveDestination(%node.getTransform(), %index == %this.targetNode);
}


//-----------------------------------------------------------------------------
function AIPlayer::aimAt(%this,%object)
{
   //echo("Aim: " @ %object);
   %this.setAimObject(%object);
   %this.nextTask();
}

//-----------------------------------------------------------------------------
function AIPlayer::pushTask(%this,%method)
{
   if (%this.taskIndex $= "") {
      %this.taskIndex = 0;
      %this.taskCurrent = -1;
   }
   %this.task[%this.taskIndex] = %method; 
   %this.taskIndex++;
   if (%this.taskCurrent == -1)
      %this.executeTask(%this.taskIndex - 1);
}


//-----------------------------------------------------------------------------
function AIPlayer::clearTasks(%this)
{
   %this.taskIndex = 0;
   %this.taskCurrent = -1;
}

//-----------------------------------------------------------------------------
function AIPlayer::nextTask(%this)
{
   if (%this.taskCurrent != -1)
      if (%this.taskCurrent < %this.taskIndex - 1)
         %this.executeTask(%this.taskCurrent++);
      else
         %this.taskCurrent = -1;
}

//-----------------------------------------------------------------------------
function AIPlayer::executeTask(%this,%index)
{
   %this.taskCurrent = %index;
   eval(%this.getId() @ "." @ %this.task[%index] @ ";");
}


//-----------------------------------------------------------------------------
function AIPlayer::targetInLOS(%this, %playerObj)
{
  //These are all of the things that can obstruct view of the Player.
  %type = $TypeMasks::PlayerObjectType | $TypeMasks::InteriorObjectType |
          $TypeMasks::TerrainObjectType | $TypeMasks::StaticShapeObjectType |
          $TypeMasks::VehicleObjectType;

  %rayedObject = ContainerRayCast(%this.getEyeTransform(),
                                  %playerObj.getEyeTransform(), %type, %this);

  if(%rayedObject == %playerObj)
    return true;
  else
    return false;
}

//-----------------------------------------------------------------------------
function AIPlayer::pointInLOS(%this, %point)
{
   // These are all of the things that can obstruct view of the Player.
   // (Other players are ignored)
   %type = $TypeMasks::InteriorObjectType |
          $TypeMasks::TerrainObjectType | $TypeMasks::StaticShapeObjectType |
          $TypeMasks::VehicleObjectType;

   %rayedObject = ContainerRayCast(%this.getEyeTransform(),%point, %type, %this);

   if(%rayedObject == 0)
    return true;
   else
    return false;  
}

(thinking code continues....)
#11
10/12/2009 (11:38 pm)

(thinking code continued....)

//-----------------------------------------------------------------------------
function AIPlayer::think(%this)
{
	// THINK ABOUT WHAT WE'RE GOING TO DO
	
	// ACTIONS: CHASE, ATTACK, FACE_TARGET, MOVE_POSITION, MOVE_TO_NODE, FOLLOW_PATH
	
	// see if dead
	if (%this.is_dead == true)
	   return;
	
   // if stuck then drop all targets
   %this.current_position = %this.getPosition();	
	%action = "";
	%this.findClosestTargets();
	
	// check current target is valid
	if (%this.current_target != 0)
	{
		if (!isObject(%this.current_target))
			%this.current_target = 0;
			
		// check will still have line of sight
		else if (!%this.targetInLOS(%this.current_target))
		{
			%this.current_target = 0;
			
			// if no los and we were chasing - then we're now moving to last know pos
			if (%this.last_action $= "CHASE" && %this.target_last_pos != 0)
				%action = "MOVE_POSITION";
		}
	}
	
	// if we are at the target_last_pos then (ie with in striking range)
	// then clear pos
	if (%this.target_last_pos != 0)
	{
      if (VectorDist(%this.getPosition(), %this.target_last_pos) <= $ZOMBIE_SPAWN::ATTACK_RANGE)
      {
         %this.target_last_pos = 0;	
         %action = "";
      }
	}
	
   //	
	// are we close enough to attack anyone
	// get range to current target (it may have changed)
	if (%this.current_target != 0)
	   %range = VectorDist(%this.getPosition(), %this.current_target.getPosition());
   else  
      %range = 0;
	
	// if current target out of range then see if there is anyone closer
	if ((%range > $ZOMBIE_SPAWN::ATTACK_RANGE || %this.current_target == 0) && %this.closest_visible_target != 0)
	{
		%cvt_range = VectorDist(%this.getPosition(), %this.closest_visible_target.getPosition());
		
		if (%cvt_range <= $ZOMBIE_SPAWN::ATTACK_RANGE)
		{
			%this.current_target = %this.closest_visible_target;
			%this.target_last_pos = %this.current_target.getPosition();
			%range = %cvt_range;
		}
	}
	
	// see if our current target is in attack range
	if (%range <= $ZOMBIE_SPAWN::ATTACK_RANGE && %this.current_target != 0)
	{
	   %action = "ATTACK";
	}
		
	// if not attacking or lining up for attack...
	if (%action $= "")
	{
		// calc distance to current, closest visible and closest target
		if (%this.current_target != 0)
		{
			%dist_current_target = VectorDist(%this.getPosition(), %this.current_target.getPosition());
			%this.target_last_pos = %this.current_target.getPosition();
			%action = "CHASE";
		}
			
		if (%this.closest_visible_target != 0)
			%dist_closest_visible_target = VectorDist(%this.getPosition(), %this.closest_visible_target.getPosition());
			
		if (%this.target_last_pos != 0)
			%dist_last_known_pos = VectorDist(%this.getPosition(), %this.target_last_pos);
			
		if (%this.closest_target != 0)
		   %dist_closest_target = VectorDist(%this.getPosition(), %this.closest_target.getPosition());
			
		// determine target based on visiblity, proximity and whether or not we're already chasing someone.
		// Will swap targets if closest is attackable and current is not
		// or if closest target is less that 1/2 this distance away that the current target
		if (%this.closest_visible_target != 0)
		{
			// if no current target then make closest visible the new target
			// or see if we want to swap current target with closest visible
			if (%this.target_last_pos == 0 || ((%dist_closest_visible_target * $ZOMBIE_SPAWN::SWAP_TARGET_RATIO) < %this.target_last_pos && %this.closest_visible_target != 0))
			{
				%this.current_target = %this.closest_visible_target;
				%this.target_last_pos = %this.closest_visible_target.getPosition();
				%action = "CHASE";
			}
			else if (%this.last_action $= "MOVE_TO_NODE" || %this.last_action $= "FOLLOW_PATH")
			{
			   %this.current_target = %this.closest_visible_target;
			   %this.target_last_pos = %this.current_target.getPosition();
			   %action = "CHASE";  
			}
		}
			
		// if we're not doing anything
		if (%action $= "")
		{
			// if currently following a path then continue following path
			if (%this.last_action $= "FOLLOW_PATH")
				%action = "FOLLOW_PATH";
			
			else
			{			
				%closest_node = %this.getClosestVisibleNode();
				
				if (getWord(%closest_node, 0) == 0)
				{
					// if no current target then track closest target
					if (%this.closest_target != 0)
					{
						%this.target_last_pos = %this.closest_target.getPosition();
						%action = "MOVE_POSITION";
					}
				}
				else
					%action = "MOVE_TO_NODE";
			}
		}
	}

(more still...)
#12
10/12/2009 (11:39 pm)
(continued)
// NOW THAT WE'VE THOUGHT ABOUT IT - SET ACTION
	switch$ (%action)
	{
		// chase after current target
		case "CHASE": // checked
         %this.followPath("");			
			//echo("c6Bot", %this,": Chasing Target:", %this.current_target);
			%this.setAimObject(0);
			%this.setMoveDestination(%this.target_last_pos);
		
		// attack current target
		case "ATTACK": 
			%this.followPath("");
			%this.setAimObject(%this.current_target);
			%this.zombieAttack(%this.current_target);
			echo("c6Bot", %this,": Attacking Target:", %this.current_target, " GRRRR");
		
		// face current target
		case "FACE_TARGET": 
			%this.followPath("");
			%this.setAimObject(%this.current_target);
			//echo("c6Bot", %this,": Facing Target:", %this.current_target);
		
		// move to a position
		case "MOVE_POSITION": 
			//echo("c6Bot", %this,": Moving to Position:", %this.current_target);
			%this.followPath("");
			%this.setAimObject(0);
			%this.setMoveDestination(%this.target_last_pos);
		
		// move to a node
		case "MOVE_TO_NODE": 
		   %this.target_last_pos = 0;
			%path = getWord(%closest_node, 0);
			%node_obj = getWord(%closest_node,1);
			%node = getWord(%closest_node, 2);
			//echo("c6Bot", %this,": Moving to Node and following Path=", %path.getName(), " Node=", %node_obj.getName());
			%this.setAimObject(0);
			%this.followPath(%path, %node);
			%action = "FOLLOW_PATH";
			
		// follow a path
		// just continue following the path
		case "FOLLOW_PATH":  
		   %this.target_last_pos = 0;
			//echo("c6Bot", %this, " Following Path: ", %this.path.getName());			
		
		// completely lost so just sit tight
		default:		
		   %this.target_last_pos = 0;
			//echo("c6Bot", %this, " Doing Nuthin");	
			%this.followPath("");
			%this.setAimObject(0);
	}
	
	%this.last_action = %action;
	%this.previous_position = %this.current_position;
	%this.schedule(%this.think_period, "think");
}



// ----------------------------------------------------------------
// locates closest target and closest visible target within search radius
function AIPlayer::findClosestTargets(%this)
{
	%this.closest_visible_target = 0;
	%this.closest_target = 0;
	%closest_visible_dist = 0;
	%closest_dist = 0;
	
	//Find all players in a given radius.
  %type = $TypeMasks::PlayerObjectType;
  %playerObj = ContainerFindFirst(%type, %this.getTransform(), $ZOMBIE_SPAWN::VIEW_DIST, $ZOMBIE_SPAWN::VIEW_DIST, $ZOMBIE_SPAWN::VIEW_DIST);
	
  while(%playerObj)
  {
      // ignore if zombie
      if (%playerObj.is_bot != true)
      {        
         // find distance to the target
         %dist = VectorDist(%this.getPosition(), %playerObj.getPosition());
         
         // see if closest target
         if (%closest_dist == 0 || %dist < %closest_dist)
         {
            %this.closest_target = %playerObj;
            %closest_dist = %dist;
         }
         
         // see if closest visible target
         if (%closest_visible_dist == 0 || %dist < %closest_visible_dist)
         {
            // do we have los?
            if (%this.targetInLOS(%playerObj))
            {
               %this.closest_visible_target = %playerObj;
               %closest_visible_dist = %dist;
            }			
         }
      }

		%playerObj = containerFindNext();
	}
}

(more thinking code to come)
#13
10/12/2009 (11:41 pm)
(thinking code still)
// ----------------------------------------------------
// RETURNS: vector with path id, node id, node index
function AIPlayer::getClosestVisibleNode(%this)
{
	%closest_node = 0;
	%closest_path = 0;
	%closest_dist = 0;
	%closest_node_index = 0;
	%ret = "0 0 0";
	
	for (%i = 0; %i < $ZOMBIE_SPAWN::PATH_COUNT; %i++)
	{
		for (%j = 0; %j < $ZOMBIE_SPAWN::PATHS[%i].getCount(); %j++)
		{
			%node = $ZOMBIE_SPAWN::PATHS[%i].getObject(%j);
			
			// is the node visible?
			if (%this.pointInLOS(%node.getPosition()))
			{
				%dist = VectorDist(%this.getPosition(), %node.getPosition());
			
				if (%closest_dist == 0 || %dist < %closest_dist)
				{
					%closest_dist = %dist;
					%closest_path = $ZOMBIE_SPAWN::PATHS[%i].getId();
					%closest_node = %node;
					%closest_node_index = %j;
				} 
			}
		}
	}

	if (%closest_node != 0)
	{
		%ret = setWord(%ret, 0, %closest_path);
		%ret = setWord(%ret, 1, %closest_node);
		%ret = setWord(%ret, 2, %closest_node_index);
	}
   
	return %ret;
}


// ----------------------------------------------------
function AIPlayer::getAngleToObject(%this, %target_obj)
{	
	//Find the vector from the AIPlayer to the player object found.
    %playerVec = VectorSub(%target_obj.getTransform(), %this.getTransform());
    %playerVec = VectorNormalize(%playerVec);
  
    //Obtain the angle between the 2 vectors. angle = acos(v1&bull;v2)
    %angle = mAcos(VectorDot(%this.getEyeVector(), %playerVec));
		return %angle;
}

// ------------------------------------------
function AIPlayer::zombieAttack(%this, %target)
{
   %target.damage(%this, %this.getPosition(), $ZOMBIE_ATTACK_DAMAGE, "Impact");
   //%target.applyDamage($ZOMBIE_ATTACK_DAMAGE);     
}


// ----------------------------------------------
// schedules respawn
function AIManager::registerDeath(%this, %id)
{
	echo("AI Death registered ID: ", %id);
	
	%id.is_dead = true;
	
	if ($ZOMBIE_SPAWN::RESPAWN_ON_DEATH == true)
	{
      %path = $ZOMBIE_SPAWN::PATHS[getRandom(0, $ZOMBIE_SPAWN::PATH_COUNT - 1)];
      schedule(10000, 0, "spawnZombieOnPath", %path);	
	}
}


and that's it! :D
#14
10/13/2009 (8:21 am)
Yikes!!!

function createTestZombie()  
{  
   echo("c6Creating Test Zombie");  
   %zombie = spawnZombie();  
   %zombie.setName("Bob");  
}

My favourite bit of the code - Bob has been my little test buddy for quite a few months now working on the navMesh stuff
#15
10/14/2009 (7:22 am)
yo thnx alot chris G but how do I make a paths and in which directory of my game should I put this.
#16
10/14/2009 (6:46 pm)
There'll be tutorials on making paths somewhere. You do it in the mission editor. The scripts are placed in server folder.

You'll need to tweak to script to suit your needs.ie.
- the path names that you've placed in the spawning code
- the shape for your characters in the PlayerData datablock

also at the end of the onServerCreated() function in server/game.cs you'll need to exec the script with the player data and then the spawning script

For the thinking code I modified the aiPlayer.cs script.

It might take a little tweaking and frustration to get it working in your game but it should give you something to play with and reverse engineer.
#17
10/15/2009 (6:26 am)
yes it worked I owe u 1 big time thnx.
#18
11/02/2009 (11:19 am)
I'm trying to implement this with the demo, and am a little lost. Could you give me some pointers as to where i should modify the code, i.e which files to implement this code, or the steps you took to make it work.

Best Regards,
T.
#19
11/02/2009 (8:10 pm)
@Tilan G: The player data and the spawning script are new scripts that should live in the scriptsAndAssets/server/scripts folder.

The thinking script is a modified version of aiPlayer.cs which in TGEA is in scriptsAndAssets/server/scripts/aiPlayer.cs - just replace the code there with what I've provided.

Also, read my previous post. I haven't tried this in T3D and keep in mind that its an intermediate level script, so if you're new to scripting you might want to try some easier things first.
#20
11/03/2009 (12:52 am)
@Rapid Fire

If you want a more user friendly AI system, check out The Universal AI Starter Kit.
Page «Previous 1 2