270 likes | 353 Vues
Learn how to create advanced stationary guards, set attributes, spawn points, and modify code to improve AI behavior. Customize AI reactions, detect threats, and implement pathed AI functionality in your game world.
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); }