Here I will show you how to make a simple mutator that allows us to alter some player properties. This tutorial assumes you know how to set up your project folder and know how to compile your package. If you do not then please follow this tutorial first Setting up your Project Folder.
First set up your project folder with a new mutator class. In this example I will call the package “MyMutator” and the mutator class “MyFirstMutator”. Because we want to create a new mutator we must extend that class. Your folder should look like this.
Your class should look like this.
Class MyFirstMutator extends Mutator;
Now we can start the really fun stuff. We want to change some player properties so we need to pick the right place (function) to start this coding. Mutators are very good for this, they allows us to spawn, destroy and change many things. A lot of mutators may take advantage of the chain of events that are called when the actor is spawned, and usually PostBeginPlay() is the preferred choice of starting function because it is called just after game play starts, near the beginning of the actors life. Fortunately for us, Mutators offer a very special function for accessing players. It is called ModifyPlayer(). ModifyPlayer() is called every time someone spawns. The Pawn being spawned or restarted by the level is passed into the function as a variable. This is the function as it appears in the Mutator class.
function ModifyPlayer(Pawn Other) { if ( NextMutator != None ) NextMutator.ModifyPlayer(Other); }
Insert the function into your mutator like this, and I will explain the code so far.
Class MyFirstMutator extends Mutator; function ModifyPlayer(Pawn Other) { //We need to always check for accessed none errors. //This is saying "if the next mutator in the chain is not equal to none (if it exists), //then call modifyplayer() in that mutator, and pass the correct variable on to it. if ( NextMutator != None ) { //This gives other mutators in the list, the chance to use this function. //if you don't give them this chance then the modifyplayer() chain will be broken and //any mutators that are added after this one will not be able to use this function. NextMutator.ModifyPlayer(Other); } }
Now lets set up the function so the players are being accessed properly.
Class MyFirstMutator extends Mutator; function ModifyPlayer(Pawn Other) { //When this function is called by the GameInfo class, it passes a variable into the "Other" //property of this function, this variable must be of type "Pawn". //So here we check that this "Other" is not equal to none, incase the player is destroyed/killed for some reason. //It's good practise to check things exist before you try to access or change them. if(Other != None) { //Now we can access the variables about the player like this //Other.SomeVariable = OurNewValue; } if ( NextMutator != None ) { NextMutator.ModifyPlayer(Other); } }
Now lets take a look at the Pawn class and see what things might be fun to change. You can view the classes right here at UT2004 Script Source. For now lets just pay attention to the defaultproperties. These are some defaults that might be fun to change.
defaultproperties { GroundSpeed=+00440.000000 //This is how fast the players moves on the ground. AirSpeed=+00440.000000 //This is how fast the player moves in the air. WaterSpeed=+00300.000000 //This is how fast the player moves through water. JumpZ=+00420.000000 //This is the ammount of acceleration applied when a player jumps. MaxFallSpeed=+1200.0 //This is maximum speed the player can land at without taking damage, a really high value basically means no falling damage (This also affects the paths that Bots can take). Health=100 //This is the starting health ammount. HealthMax=100 //The is the maxium health value that health packs can heal. SuperHealthMax=199 //Health vials and other things such as the regeneration mutator heal to this limit. }
To access these we simply use the “.” command, which lets the engine know you wish to access a property or function of the previous thing. We do it like this.
class MyFirstMutator extends Mutator; function ModifyPlayer(Pawn Other) { if(Other != None) { Other.GroundSpeed = 800; Other.JumpZ = 600; Other.MaxFallSpeed = 50000; Other.HealthMax = 200; Other.SuperHealthMax = 300; } if ( NextMutator != None ) { NextMutator.ModifyPlayer(Other); } }
To finish the mutator we need to add some defaultproperties.
class MyFirstMutator extends Mutator; function ModifyPlayer(Pawn Other) { if(Other != None) { Other.GroundSpeed = 800; Other.JumpZ = 600; Other.MaxFallSpeed = 50000; Other.HealthMax = 200; Other.SuperHealthMax = 300; } if ( NextMutator != None ) { NextMutator.ModifyPlayer(Other); } } defaultproperties { bAddToServerPackages=true //This automatically add the mutator to the serverpackages, meaning you don't have to manually change the UT2004.ini file. Description="This is my first mutator, it changes some players properties. :)" //The description of the mutator. GroupName="Player Properties" //Mutators of the same group name can't be used together. FriendlyName="MyFirstMutator" //The name that appears in the Mutator menu in game. }
Compile the code, and test it out in instant action. Choose deathmatch, pick your favorite map, add the mutator from the mutator menu and play.
You may have noticed that players are actually xPawns, (which extends UnrealPawn, and in turn extend Pawn which is why we can access them through “Other” in the ModifyPlayer() function). What if we want to change some things in xPawn? Well we can inform the engine that “Other” is actually a “xPawn” and because it is a child class of “Pawn” this will be allowed because “xPawns” inherit everything in “Pawn”. Here is an example.
function ModifyPlayer(Pawn Other) { //This means if "xPawn" (which is a subclass of "Pawn" is not equal to none). if(xPawn(Other) != None) { //Now we can access xPawn variables like this. xPawn(Other).ShieldStrengthMax = 500; //The maximum shield strength. xPawn(Other).bInvis = true; //bInvis toggles invisibility on and off. } if ( NextMutator != None ) { NextMutator.ModifyPlayer(Other); } }
We can shorten this so that we don’t have to keep typing “xPawn(Other)”. Here is an example.
function ModifyPlayer(Pawn Other) { //Declare new local variable called "x" of type "xPawn". local xPawn x; //We tell the engine that the "Pawn" is actually an "xPawn". x = xPawn(Other); //Check it exists, and that the "Pawn" was actually an "xPawn". if(x != None) { //Change things as before but this time we need only type "x". x.ShieldStrengthMax = 500; x.bInvis = true; } if ( NextMutator != None ) { NextMutator.ModifyPlayer(Other); } }
Thats all for this tutorial. Well done if you made it this far.
TIP – Mutators can be used to change almost anything. Just be creative.
I am so greatful for the work you put into making these tutorials. I’m starting on an awesome journey because of your tuts! 🙂