Spawning and Controlling a Bot
This question I have noticed gets asked a lot on the Unreal Forums. In fact I was one of those who asked the question, and after numerous tries and asking around. I eventually found the answer. So I decided that a Unreal Wiki Page should be written about it. You can look at forum discussion I had about it where I final got it to work at 123677.
Now on to some work. The first thing you need to understand is how to make a gametype.
See Link: INT File.
Okay now we will be creating 3 classes. The first on is going to be a new xDeathMatch subclass. The only really thing we are going to do in this class is to rewrite the SpawnBot function. Just cut and copied the spawn function from the DeathMatch class and changed the thinks in bold. So our class should look like:
class NewDeathMatch extends xDeathMatch; function Bot SpawnBot(optional string botName) { local Bot NewBot; local RosterEntry Chosen; local UnrealTeamInfo BotTeam; BotTeam = GetBotTeam(); Chosen = BotTeam.ChooseBotClass(botName); //set the pawn class name and pawnclass to our own pawn class Chosen.PawnClassName = "MutSpawningBot.NewPawn"; Chosen.PawnClass = class'MutSpawningBot.NewPawn'; //comment out these because the because we just set the pawnclass /* if (Chosen.PawnClass == None) Chosen.Init(); //amb // log("Chose pawn class "$Chosen.PawnClass); */ NewBot = Bot(Spawn(Chosen.PawnClass.default.ControllerClass)); if ( NewBot != None ) InitializeBot(NewBot,BotTeam,Chosen); return NewBot; } defaultproperties { MapPrefix="BS" BeaconName="BS" GameName="NEW DeathMatch" }
Note the function Spawnbot was provided with assistance by smattbac. Now we will make our new Pawn class that will be a subclass of xPawn class.
class NewPawn extends xPawn; //used to just show that the class has been initalized event PostBeginPlay() { Super.PostBeginPlay(); Log("Pawns begin Play"); } //assign our controller class through the default properties defaultproperties { ControllerClass=class'MutSpawningBot.NewController' }
And our last class will be the Controller class where we will make a subclass of the xBot class.
class NewController extends xBot; //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. 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.
Now when you load up UT2k3 change the Bot count to 1. Type in the following console command: showdebug and if your controller says: NewController and your Pawn says: NewPawn then there you have it the bot is now under your control.:)
Here is another way of doing the same thing that was sent to me:
These provided by NickR
class YourGame extends TeamGame; function Bot SpawnBot(optional string botName) { local Bot NewBot; local RosterEntry Chosen; local UnrealTeamInfo BotTeam; BotTeam = GetBotTeam(); Chosen = BotTeam.ChooseBotClass(botName); if (Chosen.PawnClass == None) Chosen.Init(); NewBot = Spawn(class'YourPackage.YourAIController'); if (NewBot != None) InitializeBot(NewBot, BotTeam, Chosen); return NewBot; } defaultproperties { PlayerControllerClassName="YourPackage.YourPlayerController" DefaultPlayerClassName="YourPackage.YourPawn" }
class YourAIController extends AIController; function SetPawnClass(string inClass, string inCharacter) { Super.SetPawnClass("YourPackage.YourPawn", inCharacter); } defaultproperties { PawnClass=class'YourPackage.YourPawn' }
class YourPlayerController extends PlayerController; function SetPawnClass(string inClass, string inCharacter) { Super.SetPawnClass("YourPackage.YourPawn", inCharacter); } defaultproperties { PawnClass=class'YourPackage.YourPawn' }
Related Topics
Discussion
Miszt: I keep geting "Cant find class MutSpawningBot.NewPawn" when I compile, I guess I'm missing somthing here as I dont have MutSpawningBot in any of my UT dirs...I'm a total n00b btw, so please dont shout at me for being dumb :P (also apologies if I shouldnt be adding my question here)
Toeses: The second method doesn't work, you get a type mismatch on the line NewBot = Spawn(class'YourPackage.YourAIController'); makes sense really, you can't spawn an AIController and cast it to a bot can you?
Wormbo: For obvious reasons you're supposed to create your own subclass of Bot (which is an indirect subclass of AIController) and specify that in the Spawn() call, hence the page name "Spawning Your Own Bot".
Juxtapose: I'm having the same problem as Miszt above. I'm a total n00b as well, but I don't see any follow up . . . I will try making a MutSpawningBot.NewPawn class in a separate file (and otherwise blank, i'm thinking) later and post again to let you know how it goes.
Juxtapose: I got my error to go away by carefully retyping my class names; I hope for Miszts sake that his error was that simple as well.
So my code is compiling but not working. There is no direct mention of how to enable the game type. 'NewDeathMatch' doesn't show up under the available game types. Also, showdebug is an unrecognized command in the UT2k4 console. I'll try harder tonight but I think the page itself could use some touching up and more comments between the code. In particular, the intro header says ". . . The first thing you need to understand is how to make a gametype" but doesn't link anywhere too useful (at least that I can understand). Maybe a separate page on creating a custom gametype is in order? I'll do it myself once I know what I'm talking about and if no one else wants to step up.
Moonfisher: Hey I got the same error Jux, it's because you have no maps for that gametype, the prefix is BS in the code above, so if you copy a deathmatch map (Or any map realy) and rename the prefix to BS your gametype should apear in the menu.
In case anyone else found this confusing (As I did).
The bots you spawn will start fighting eachother and will have the AI that you assigned in the game rules. Now I'm only just starting this myself, so don't take my word for anything I say, and please correct me if I'm wrong :
Because our NewController extends the xBot class wich extends the Bot class, you need to overide the functions in the Bot class that you want to controll 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 apretiate it, till then I would sugest getting to know the Bot class, that's what I'll be doing.