How To: Create Actions and Key Mappings for Actors in C#

Originial Source, -Royce Tucker, Lead Programmer of 40 Past Midnight

 Today I'll will be talking about custom input, primarily through keymaps.

A keymap binds a key press to a command. Unless you make your own list of commands, you'll have to look at AvatarCommands. I'll make a brief command class to show how it is handled.

public class MyInputEventnames : IdNames
{
    public static readonly NameID Attack = new NameID("Attack");
    public static readonly NameID Jump = new NameID("Jump ");
    public static readonly NameID DoSomethingElse = new NameID("DoSomethingElse");
}

These NameIDs basically allow us to keep track of and call any event we could want to trigger.

Open up the World file for your project. We'll add the keymap to OnInitialized. If it isn't already there, make it like this:

protected override void OnInitialized()
{
    base.OnInitialized();

    // Create the keymap
    new KeyMap( "MyKeyMap", KeyMap.Ids.FullMouseHandlerKeyCodes,

        // List the entries
        new KeyMapEntry(Key.Enter, MyInputEventNames.Attack, false),
        new KeyMapEntry(Key.Space, MyInputEventNames.Jump, false),
        new KeyMapEntry(Key.Q, MyInputEventNames.DoSomethingElse, true)
    );

    // Create the input controller and add it to the world
    ActorInputController myInputLauncher = new ActorInputController( "MyControls", "MyKeyMap", 1f, 1f );
    Library.InputControllers.Add( myInputLauncher );
}

The bool variable used as the last parameter for a KeyMapEntry is whether or not the command will automatically stop when the key is lifted up. Setting this to false for an animation trigger will force an animation to play through the entire animation before playing another.

Now that we have the keymap in place, we need to make an action of some kind trigger. The best place for these actions is in a custom avatar class. If you want to add these to an avatar, do this:

// In the constructor, link the Avatar to the new input controller:
DefaultAvatarControllerName ="MyControls";

// Bind the input in OnConstructPrototype()
// For animations:
if( Animations.Count == 0 )
{
    AnimationSet.ConfigureAnimations
    {
        new Animation( MyInputCommands.Jump, animationName, animationSpeed, acceleration, false, false )
    }
}

This would bind the space key to the character's jump animation. The last two boolean parameters in the Animation function are loop and canAbort. These are self explanatory.

To call a custom function, you would do this:

// Also in OnConstructPrototype():
CommandSpec[] newCommands = new CommandSpec[]
{
    new CommandSpce( MyInputCommands.Attack, new MethodCommand(new StandardMethod( CustomAttackFunction )))
};
AddCommands( newCommands );

Then, if you make the function:

public void CustomAttackFunction( object args )
{
    // Add custom attack code here
}

CustomAttackFunctionwould be called when the enter key was pressed.


You can trigger command through any input handler like this, as well:

// Inside any class is capable of handling input, such as AvatarInputController
public override void OnHandleInputEvent( IInputHandler inputHandler, InputEventArgs inputEvent )
{
    if( inputEventArgs.Key == Key.MouseButtonLeft )
    {
         if( inputEventArgs.WasPressed )
         {
              ExecuteUserCommand( MyInputCommands.Attack, null );
         }
     }
}

The above code would trigger the custom attack function when the left mouse button was clicked.

As a side note, the reason that all of these various commands can be used for the same functionality is because they all link at some point. AnimationSets get added to a command spec that executes a StartAnimation command. Command specs call ExecuteCommand function. If you wanted, you could write all of your animation code using ExectureUserCommand; however, it would be much easier to make use of the AnimationSets and CommandSpecs that are available for you.

Thats about all I have for this tutorial. Hopefully you have gained a better understanding of how input is handled in V3D.