270 likes | 350 Views
Enemy AI. CIS 487/587 Bruce R. Maxim UM-Dearborn. Slides based on the Code from Advanced 3D Game Programming by Kenneth Finney. Stationary Guard - 1. Requirements Visually detects potential threats Determines friend or foe Determines threat level Scans assigned area
E N D
Enemy AI CIS 487/587 Bruce R. Maxim UM-Dearborn
Slides based on theCode from Advanced 3DGame Programmingby Kenneth Finney
Stationary Guard - 1 • Requirements • Visually detects potential threats • Determines friend or foe • Determines threat level • Scans assigned area • Engages hostile players • Detects when being engaged by hostile players
Stationary Guard - 2 • Attributes • Maximum vision range • (differs for each guard) • Minimum vision range • (guaranteed detection distance) • Alertness • (some are better and some are worse) • Attention level • (gets worse with no activity) • Aggressiveness • (not always the same for each guard)
AIDropPoints • Execute the fps.starter demo and open the World Creator Interface • On lower right side, drill down and click on MissionObjects/System/SimGroup • Call the object AIDropPoints and switch to the World Editor Inspector (F3) • Make AIDropPoints an instant group using the Alt key and left mouse button
Guard • Switch to the World Creator (F4) • On lower right side, drill down and click on MissionObjects/System/SimGroup • Call the object Guard and switch to the World Editor Inspector (F3) • Make Guard an instant group using the Alt key and left mouse button
SpawnSphere - 1 • Exit the Mission Editor (F11) and enter camera fly mode (F8) • Find a good location for an AI character and place it 20 feet off the terrain • Switch back to the Mission Editor (F11) and enter World Creator (F4) • Drill down to Shapes/Misc on lower right and click on SpawnSphereMarker • Place at least two more in the world
SpawnSphere - 2 • Switch to World Editor Inspector (F3) • Select all 3 SpawnSpheres in upper left (Ctrl and left mouse click) • Click on expand all • Changes the radius field to 10 and press Apply button
SpawnSphere - 3 • Select all 3 SpawnSpheres in upper left (Ctrl and left mouse click) • Add the following dynamic field and values to each • aggression 100 • range 100 • attention 100 • alertness 100 • Save the mission and exit to the desktop
Code Modifications • Add this line to the server\script\game.cs function onServerCreated exec(“./aiGuard.cs”); • At the end of the startGame() function in the same game.cs file add this line to start the bot placement process Schedule(3000, 0, “CreateBots”); • Save game.cs and copy the file aiGuard.cs to the server\script folder
checkForThreat function AIGuardDB::checkForThreat(%this,%obj) { DebugPrint( "%this:"@%this@"~AIGuardDB::checkForThreat (from:"@%obj@")", "checkForThreat"); if(!isObject(%obj)) return; // modified to allow firing %idx = %obj.getClosestEnemy(); if (%idx < 0) return 0; %target = ClientGroup.getObject( %idx );
checkForThreat if ( !%obj.CheckArcOfSight(%target.player) ) %testRange = %obj.range / 2; else return; if ( %obj.GetTargetRange(%target.player) < %testRange) { return %target.player; } DebugPrint( "no threat (from:"@%obj@")", "checkForThreat"); return 0; }
Testing Guard AI • When the player avatar gets close enough for the Guard to see it, the player will be attacked until killed or the player moves out of range • The Player is not able to inflict any damage on the Guard (a definite need in real game)
PathedAI • The fps.starter contains the script server\scripts\aiPlayer.cs • Add the following to the end of aiPlayer.cs function InsertPathedAI() { %player = AIPlayer::spawnOnPath("Follower","MissionGroup/Paths/PathB"); %player.mountImage(CrossbowImage,0); %player.setInventory(CrossbowAmmo,1000); %player.followPath("MissionGroup/Paths/PathB",-1); }
Path Definition - 1 • Find a relatively flat area where it will be easier to create a path and hit F11 to open the Mission Editor and switch to "World Editor Creator" mode. • Expand the tree in the lower right half of the screen by clicking the "Mission Objects" entry. Expand it out like so: "Mission Objects->Mission"
Path Definition - 2 • In the "Mission" directory, you should see several entries to choose from. • Click the entry labeled "Path" just once to create a new Path object. Name the Path object, “PathB". • In the "MissionGroup" tree, which is in the upper right hand side of the editor, expand out the tree and find the node labeled "PathB".
Path Definition - 3 • Make this node the current selection by holding down the "Alt" key while clicking it with the mouse. • If done correctly, the selection color of the "PathB" entry should change from white to gray. Make sure the path markers get grouped under our new Path object. • Return to the tree control in the lower right hand corner and click the “PathMarker” in the "Mission" directory.
Path Definition - 4 • Name the new PathMarker, “wp1" and check to make sure it was correctly grouped under "PathB" in the "MissionGroup" tree control. • Repeat the process to create two more PathMarkers called, “wp2, and “wp3". • Make sure to place them far enough apart so you can see your bot run around. • Save the mission file and exit to the desktop
Test PathedAI • Run the test application again. • Move the player avatar to a location near the path defined by PathB • Open the console and type InsertPathedAI( ); • Close the console window and watch it go
PathedAIShooter • Define another path called PathA • Insert the following line of code in the aiPlayer::aimAt function %this.setAimLocation(%object.getPosition()); after the line %this.setAimObject(%object); • You will also need to add the function InsertPathedAIShooter to the file aiPlayer.cs
InsertPathedAIShooter - 1 function InsertPathedAIShooter() { %player = AIPlayer::spawnOnPath("Shooter","MissionGroup/Paths/PathA"); %player.mountImage(CrossbowImage,0); %player.setInventory(CrossbowAmmo,1000); // Maxim added code %player.followPath("MissionGroup/Paths/PathA",-1); %player.pushTask("playThread(0,\"celwave\")"); %player.pushTask("followPath(\"MissionGroup/Paths/PathA\")"); %player.pushTask("aimAt(\"MissionGroup/target\")"); %player.pushTask("wait(10)");
InsertPathedAIShooter - 2 %player.pushTask("fire(true)"); %player.pushTask("wait(1)"); %player.pushTask("fire(false)"); %player.pushTask("wait(10)"); %player.pushTask("fire(true)"); %player.pushTask("wait(1)"); %player.pushTask("fire(false)"); %player.pushTask("playThread(0,\"celwave\")"); %player.pushTask("done()"); }
Testing Shooter • Open the World Creator and place a logo some where near PathA • Label the logo “Target” and save the mission • Start demo and open the console window • Type the following to test the shooter once the player avatar can view PathA InsertPathedAIShooter( );
Combining Them • It is possible to have a moving enemy that also shoots at you • I have not finished my version yet, but you might try looking at the AI Guard Unit on the Torque web site (this will require recompiling Torque to add a new class) • Finney’s version does not require recompilation of Torque
Chasing • Add the following code where setAimObject is called if (%theRole !$= “Guard”) { %obj.setMoveSpeed($MAX_CHASER_SPEED); %obj.setMoveDestination(%tgtPlayer.getPosition( )); %obj.nextBlockCheck = %this.schedule($MAX_SCAN_GAP*2), “unblock”, %obj); }
Unblock // used to help AI when they get stuck function AIGuardDB::unblock(%this,obj) { if (!isObject(%obj)) return; cancel(%obj.nextBlockCheck); %this.setRandomDestinatioin(%obj); }