1 / 73

Sega 500

Sega 500. Custom Scripted Actions. Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles. Thus far. We’ve played with both Scripted events and sequences for our pawns and found them to be quite similar.

Download Presentation

Sega 500

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Sega 500 Custom Scripted Actions Jeff “Ezeikeil” Giles jgiles@artschool.com http://gamestudies.cdis.org/~jgiles

  2. Thus far • We’ve played with both Scripted events and sequences for our pawns and found them to be quite similar. • Not to mention that we had some fun making our bot get squashed and run in circles.

  3. Today • Although the current actions list is quite extensive, without surprise, there is some functionality which is not included. • So we’re going to build our own.

  4. What are we building? • Well, one of the few things thing that I found I could not do in the list was cause the creation of a pawn with AI. • Sure, we could create the pawn, but there was no attachment to a controller.

  5. What are we building? • I’ve found 2 methods that work well to create a pawn at a specific location and both are fairly straight forward. • The first relies almost exclusively on the current functionality for adding bots

  6. What are we building? • The second, has a bit more to it, but if gives more direct control over the pawns creation.

  7. Setup • Both of the classes derive from scriptedaction class Action_CreateBot extends ScriptedAction; • These will auto-magically appear in the pull down menu of our actions list in the editor.

  8. About Scripted Actions • Actually, setting up a new action is really quite easy. • All the magic happens around one function: function bool InitActionFor(ScriptedController C)

  9. About Scripted Actions • Although there are a one or twocases where it is not used, it’s fairly safe to say that anything we want to implement will be called from here.

  10. The easy way • Starting by getting the bot into the game at any player start point, we just need to call a few function that already exist in our game type.

  11. The easy way • The trick lies in accessing these functions. • The ones we’re after are: • SpawnBot. • RestartPlayer. • Both of which are defined in the Deathmatch game type.

  12. The easy way • The nice part is that any gametype we use will have this class as a parent.

  13. The easy way • So how do we get there from here? • As you already know, the game is accessible from just about anywhere in the code. • It just takes some typecasting.

  14. The easy way • I our case, we’re given a controller, which can see the level. • And the level knows about the game, so we can safely cast to our parent class. DeathMatch(c.Level.game)

  15. The easy way • Cool! • So getting our bots in is just a matter of accessing these functions… local bot newBot; newBot = DeathMatch(c.Level.game).SpawnBot(); c.Level.game.RestartPlayer(NewBot);

  16. The easy way • And this spawns our dude into the level when this script is hit. • And because we’re using the existing functions, all the initializations are taken care of for us…gota like that!

  17. The easy way • But spawning him at a random start point is not always what we want. • So how to we tell UT where to spawn something?

  18. The easy way • Well UT’s spawn function takes parameters, one of which is location…should be simple no? • Just do an allactors search and match up a tag to an object…simple.

  19. The easy way • But there’s a problem. We don’t have an allactors iterator…can’t see it, can’t access it. • We derive off object, not actor where all our iterators are defined. • …so, does this mean we’re screwed?

  20. The easy way • Well, no…the cost of admission just goes up. • Object has a single iterator for us to use. AllObjects <Shudder>

  21. The easy way • So we can get to any object’s tag, we just have to iterate over ALL the objects in the game. • Expensive.

  22. The easy way • It works just like any other iterator native(197) final iterator function AllObjects (class baseClass, out Object obj);

  23. The easy way • So how do we us it then… • And inside the InitActionFor function: var(AIBOT) name loctag; // what we’re looking for

  24. The easy way foreach AllObjects(class'Actor', A) { if( a.Tag==locTag ) { newBot = DeathMatch(c.Level.game).SpawnBot(); c.Level.game.RestartPlayer(NewBot); NewBot.SetLocation(A.Location); newbot.Pawn.SetLocation(A.Location) } }

  25. The easy way • And TA-DA! It’s in! Spawn anywhere. • But there’s a *small* catch to this method. • The restartplayer call causes a spawn at the player start in the conventional manner

  26. The easy way • An then we set the players location to where we want him. • However, this leaves the spawn effect at the start point.

  27. The easy way • So this works, but we can’t have this effect happening where the player can see it. • On to method number two, which is quite similar. We just change the guts of the InitActionFor function.

  28. A better way • And add a bit more in the set up. • This method also allows us to define which controllers and pawn we want to use. var(AIBOT) name objecttag; //Where to spawn var(AIBOT) class<bot> bType; //What Bot type var(AIBOT) class<Pawn> pType; //What pawn Type

  29. A better way • And in the InitActionFor function, we redefine it as: function bool InitActionFor(ScriptedController C) { local bot newBot; local Pawn newPawn; local actor A; local UnrealTeamInfo BotTeam; local RosterEntry Chosen;

  30. A better way • The UnrealTeamInfo and RosterEntry are needed to properly initialize the bot. • Everything else is a handle to an object that we’ll create here.

  31. A better way • We keep the same search method…not much of a choice  foreach AllObjects(class'Actor', A) { if( a.Tag==locTag ) {

  32. A better way • Spawn a pawn and a controller at the desired loaction, based on our search result (Actor a) newBot = c.Level.Spawn(bType,,,a.Location, a.Rotation); newPawn = c.Level.Spawn(pType,,,a.Location, a.Rotation);

  33. A better way • So they’re both in the game but need to be added to the game roster and initialized BotTeam=DeathMatch(c.Level.game).GetBotTeam(); Chosen =BotTeam.ChooseBotClass(); Chosen.Init(); DeathMatch(c.Level.game).InitializeBot(newBot,BotTeam , Chosen);

  34. A better way • And lastly, we need the controller to own the pawn. This is done with the Posses function. newBot.Possess(newPawn);

  35. A better way • Give it a run, it works nice… ...but there’s something missing…

  36. A better way • The pawn comes in, with a brain, great! • But where the heck is the gun!

  37. A better way • And, notice that once you frag them, spawn back into the game with all there toys. • So we missed something…

  38. A better way • Actually, just one line…ain’t that always the way? • If you route through the deathmatch class you find this function AddDefaultInventory( pawn PlayerPawn )

  39. A better way • And it does, just what the name says… • Accessing it is nothing new as well, DeathMatch(c.Level.game).AddDefaultInventory(newPawn);

  40. A better way • Lastly, in our default properties, we need to set the ActionString to something meaningful. ActionString="Spawn EzeBot"

  41. A better way • As best I can tell, the action string is used exclusively for debug purposes and this is the text that is thrown to the screen. • This is done from the ScriptedSequence object. Beyond that, I’ve not found any functionality.

  42. That’s all well and good… • But, continually adding bots is only so much fun. • The real fun lies in killing them off

  43. Killing our pawn • So, from our scripted sequence, time to do that. • This part is actually really easy if you controller already has a pawn associated to it…Well go over how to get one in a minute if it doesn’t.

  44. Killing our pawn • So the new action I defined as: class Action_Gib extends ScriptedAction; function bool InitActionFor(ScriptedController C) { c.Pawn.ChunkUp(c.Pawn.Rotation, 1.0); c.Pawn.PlaySound(sound'PlayerSounds.Final.Giblets1'); return true; //must return true or UT crashes }

  45. Killing our pawn • Yup, that’s the whole thing. • The actual kill is build into the pawn already, it’s just a matter of accessing it. • Can you guess what it does?

  46. Killing our pawn • Before:

  47. Killing our pawn • After: SPLAT!  However, I am a bid confused as to how he got 2 skulls though…

  48. Killing our pawn • Yup, it turns our pawn into a bunch of giblets. • The best thing is, you can now just add this to the list of Scripted events for your AIScript.

  49. Killing our pawn • So long as you have a pawn associated with it that is…

  50. Integration into Gameplay • Ok, I believe that it’s great for telling stories to the player and watching things happen. • But can the player interact with it? • In a word, yes.

More Related