This guide demonstrates how you can use the Mutator class UDK offers to implement custom key bindings. I personally don't know if there is a better way to accomplish this, and I do know this isn't how you're normally supposed to use mutators. Either way, let us begin to create a custom key binding.
This guide does not cover how to create a mod, where to put files, how to compile and other similar tasks. If you do not know this information yet, please refer to different guides first (I.e. Your First Skin Mod).
Creating a mutator class is as simple as extending Mutator. Since we'll be reacting to custom mutate commands, we'll also need the Mutate function. You can copy the below function as a base.
Keep in mind that your Mutate function should always call Super.Mutate(...)
, as seen in the example.
MyMutator.uc
:
class MyMutator extends Mutator;
function Mutate(string MutateString, PlayerController Sender)
{
Super.Mutate(MutateString, Sender);
}
The Mutate
function will be called whenever the command mutate .....
is called. What comes after mutate
is passed as the MutateString
parameter.
A switch allows us to respond only to messages we care about.
class MyMutator extends Mutator;
function Mutate(string MutateString, PlayerController Sender)
{
switch(Locs(MutateString))
{
case "mymessage":
MyFunction();
break;
}
Super.Mutate(MutateString, Sender);
}
function MyFunction()
{
`broadcast("My function executed.");
}
As the above code makes use of Locs
(lowercase), the mutate command can be entered case-insensitive.
This is where we deviate from actual mutators. As AHiT doesn't have a mutator selection menu, we have to improvise.
Keep in mind that the GameMod classes can be used to accomplish a lot of the things mutators can do. This is why we're only looking at mutators for bindable actions (using the Mutate function)!
To enable the mutator in-game, we'll be adding the mutator from our GameMod. So first, let's create a GameMod class.
MyMutatorMod.uc
:
class MyMutatorMod extends GameMod
config(Mods);
var MyMutator mutator;
event OnModLoaded() {}
event OnModUnloaded() {}
Now, we have to add the mutator to the world info, allowing the Mutate
function to be called. This also differs from the normal implementation, because normally the code adds a mutator from a string (mutator class name), but that makes it more difficult to destroy the mutator when the mod is unloaded.
MyMutatorMod.uc
:
class MyMutatorMod extends GameMod
config(Mods);
var MyMutator mutator;
event OnModLoaded()
{
local WorldInfo wi;
wi = class'WorldInfo'.static.GetWorldInfo();
mutator = Spawn(class'MyMutator');
if (wi.Game.BaseMutator == None)
wi.Game.BaseMutator = mutator;
else
wi.Game.BaseMutator.AddMutator(mutator);
}
event OnModUnloaded()
{
mutator.Destroy();
}
Note: In this example we're assigning a binding to a key without checking for any previous bindings. This may make other actions inaccessible, since users can not bind actions in-game yet! Please don't use commonly used keys (I.e. WASD).
At this point you should have a working mutator, that is loaded and unloaded by the GameMod class. You can test if your Mutate
function works by using mutate
in the console (I.e. mutate MyMessage
).
The last step is to bind a key to your message. We can do this in the GameMod class as well.
Note the difference between ''
and ""
. The function SetBind
expects a Name for the key, and a string for the command. There's a slight difference between these two types, but to keep it simple: Use ''
for names and ""
for strings.
You also need to put your key in a variable, you can not put 'NumPadOne'
directly in the SetBind
function. This has to do with the function expecting an out
parameter for.. reasons.
MyMutatorMod.uc
:
class MyMutatorMod extends GameMod
config(Mods);
var MyMutator mutator;
event OnModLoaded()
{
local WorldInfo wi;
local Hat_PlayerController pc;
local Name npOne;
wi = class'WorldInfo'.static.GetWorldInfo();
pc = Hat_PlayerController(GetALocalPlayerController());
npOne = 'NumPadOne';
// Set Mutator
mutator = Spawn(class'MyMutator');
if (wi.Game.BaseMutator == None)
wi.Game.BaseMutator = mutator;
else
wi.Game.BaseMutator.AddMutator(mutator);
// Set binding
pc.PlayerInput.SetBind(npOne, "mutate MyMessage");
}
event OnModUnloaded()
{
mutator.Destroy();
}
The sample code will log a message whenever you hit NumPadOne
(assuming you have NumLock on). If your bindings don't work, try disabling and enabling the mod, see if your code differs from the sample code, and see if the binding is not overridden by another mod or the game itself.
You should be able to find the key binding in \HatinTime\HatinTimeGame\Config\HatinTimeInput.ini
:
Bindings=(Name="NumPadOne",Command="mutate MyMessage",Control=False,Shift=False,Alt=False,bIgnoreCtrl=False,bIgnoreShift=False,bIgnoreAlt=False)