The three virtues of a programmer: Laziness, Impatience, and Hubris. – Larry Wall

UE3:Spawning Your Own Bot

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

Spawning and Controlling a Bot[edit]

Adapted the legacy scripts from this earlier page http://wiki.beyondunreal.com/Legacy:Spawning_Your_Own_Bot to the most recent UT version (UT3/UE3)

Assuming all the scripts are compiled from mod folder 'FirstMutator' - didn't see where it was necessary to select 'FirstMutator' from gameplay to invoke the new controller.

After successful compilation

*start ut3 with '-windowed' option since you'll want to check the log via 'showlog' to see the changes in effect
*choose the 'NewDeathmatch' gametype
*enter game with no bots
*from command console enter 'showlog' which will pop up a dos window log
*from command console enter 'addbots 1' which will create a bot and print 'New SpawnBot' and 'New Roaming State' in the log

If you want to view what the bot is thinking, etc from the console command enter 'viewclass pawn' to enter a spectator state and then 'showdebug' to display the current bot state, etc. In Unrealed the weapon forward/backward will send you to the next bot in spectator mode, not sure how to do this from the game.

class NewDeathMatch extends UTDeathMatch; 
 
/* Spawn and initialize a bot
*/
function UTBot SpawnBot(optional string botName,optional bool bUseTeamIndex, optional int TeamIndex)
{
	local UTBot NewBot;
	local UTTeamInfo BotTeam;
	local CharacterInfo BotInfo;
 
	BotTeam = GetBotTeam(,bUseTeamIndex,TeamIndex);
	BotInfo = BotTeam.GetBotInfo(botName);
 
        //JTC - the below two lines are the only line changes from the original for our version of the function
        LogInternal("New SpawnBot");
	NewBot = Spawn(class'FirstMutator.NewController');
 
	if ( NewBot != None )
	{
		if (SinglePlayerMissionID != INDEX_NONE && BotName != "" && BotName != BotInfo.CharName)
		{
			WarnInternal("Single player bot" @ BotName @ "could not be found (bad spelling?)");
			bBadSinglePlayerBotNames = true;
		}
		InitializeBot(NewBot, BotTeam, BotInfo);
 
		if (BaseMutator != None)
		{
			BaseMutator.NotifyLogin(NewBot);
		}
	}
 
	return NewBot;
}

Controller class where we will make a subclass of the UTBot class.

class NewController extends UTBot;
 
//copied from bot class
function SetAttractionState()
{
        if ( Enemy != None )
                GotoState('FallBack');
        else
        { //want to change this to whatever your default state is you   
               //want for your bot.
                LogInternal("New Roaming state");
                GotoState('Roaming');
 
        }//close if
}

As far as I can tell the only way to get the controller to start in whatever your default state is, you must override the Function function SetAttractionState() and change the GotoState(‘Roaming’) to whatever your state is. I have tried using auto state but it doesn’t seem to work. Heed this advice - the game will ignore the code under your Begin: labels inside of your initial state until after reaching this settling point.


Related Topics[edit]

Discussion[edit]

Because our NewController extends the UTBot class wich extends the Bot class, you need to overide the functions in the Bot class that you want to control youself.

A good way to start off getting your bots to just stop and do nothing is to overide the Roaming state from the Bot class (In your NewController class) :

state Roaming
{
	ignores EnemyNotVisible;
Begin:
	SwitchToBestWeapon();
	WaitForLanding();
DoneRoaming:
}

You can check the properties for the Bot class, but it doesn't list or explain most of the functions and states that you'll want to overide though. There are some coments in the source, but far from all functions are explained.

If someone has a link to a good reference or further guidance on making an AI for a Bot I'd appreciate it, till then I would suggest getting to know the Bot class, that's what I'll be doing.

jcothran: I'm adding the below script as well although I couldn't figure out how to get the bot Pawn to use the class 'NewPawn' or how that part of the legacy documentation was useful.

class NewPawn extends UTPawn;
 
//used to just show that the class has been initalized
simulated event PostBeginPlay()
{
        Super.PostBeginPlay();
        LogInternal("Pawns begin Play");
}
//assign our controller class through the default properties
defaultproperties
{
        ControllerClass=Class'FirstMutator.NewPawn'
}


Phloxicon That tutorial was good but I wanted to put an NPC into the map using the unreal editor. Here's the code I used to do it:

class NPCPawn extends UTPawn
      placeable;
 
function SpawnDefaultController()
{
	Super.SpawnDefaultController();
}
 
defaultproperties
{
  ControllerClass=Class'YourPackageNameHere.NPCBot';
}

This code let's you create a physical character can that be placed into the world using the editor.

The following code is used to change the behaviour of your bot:

class NPCBot extends UTBot;
 
//copied from bot class
function SetAttractionState()
{
        if ( Enemy != None )
        {         
                `log("New FallBack state");
                GotoState('FallBack');
        }
        else
        { //want to change this to whatever your default state is you   
               //want for your bot.
                `log("About to enter MyState");
                GotoState('MyState');
 
        }//close if
}
 
//the bot will never leave this state
//it will just output the message
//you must add your own content
state MyState
{
Begin:
      `log("In MyState");
DoneMyState:
}

To place the character, open the Generic Browser in the Unreal Editor (by clicking the blue and white square which is usually in between the clipboard "paste" icon and the Kismet "K" icon), click on the "Actor Classes" tab, and expand the Pawn, then GamePawn and then UTPawn class. NPCPawn should be visible. Click on it and then close (or move) the generic browser window. Place the NPCPawn into the level by right-clicking on the place you would like your NPC to appear and select "Add NPCPawn Here" from the menu. Now your NPC is in the world. Because the ControllerClass in the NPCPawn class defaults to NPCBot, the AI behaviour of the NPC will be contained within the NPCBot file. Any changes you make to the NPCBot class will be reflected in the behaviour of the NPCPawn when you run the level.

To run the level, right-click on the floor somewhere in your level and select "Play From Here" in the menu WHILE holding Ctrl. This will start the level in spectator mode. Once in spectator mode, left-click once to become a spectator of our new NPCPawn. If you've copied my code exactly, the NPCPawn will just be standing still. Make sure that the correct classes are being used on the pawn by activating the console (by pressing the tab button on your keyboard) and type the command "showdebug" but without the quotation marks. This should show information about the character in the top left of the screen. If, somewhere in that information, it says "NPCPawn" and "NPCBot", you've set up your files correctly and the Bot is indeed under your control. To view the log of everything that has happened in the level so far, enter the command "showlog" in the console. This should bring up a blank DOS-like black screen.

If you want to be absolutely sure that your bot is in the NPCBot script, exit the level by pressing Escape (Esc) when the level viewer window is selected - don't close the log window. Once the level is closed, restart it again in spectator mode. Now view the log window and there should be a log entry of "In MyState". This indicates that it has entered the state correctly. If the log window won't become visible, try right-clicking it in the task-bar and selecting "Maximize".

Also, if you want one of your state to be the starting state of your bot, put the word "auto infront of the state name like so:

// This is the automatic state to execute.
auto state Idle
{
   // When touched by another actor...
   function Touch( actor Other )
   {
      log( "I was touched, so I'm going to Attacking" );
      GotoState( 'Attacking' );
      Log( "I have gone to the Attacking state" );
   }
Begin:
   log( "I am idle..." );
   sleep( 10 );
   goto 'Begin';
}

More info on states can be found here: http://udn.epicgames.com/Three/UnrealScriptReference.html#Overview%20of%20States