Chapter 4

<< Prev Chapter

Animations (Mecanim)

In this chapter we will explain how to replicate animations over the networking using Bolt. There are many ways to do this, even many ways inside Bolt, we are going to look at the default way of replicating mecanim parameter state over the network. This chapter will be rather short, as there is not that much to write about mecanim replication, but it's such an important topic that it deserves its own chapter.

Creating A Mecanim Asset

The first thing we are going to do is to hook up the Animator Controller for the character we are using, you can find the controller in bolt_samples/AdvancedTutorial/art/models/sgtBolt/sgtBolt4merged. Follow the next steps:

  1. Select the sgtBolt4Merged-ModelOnly sub-object on your TutorialPlayer prefab;
  2. Open the folder bolt_samples/AdvancedTutorial/art/models/sgtBolt;
  3. Find the Animator Controller sgtBolt4merged;
  4. Drag it into the Controller slot on the Animator component;
  5. Disable Apply Root Motion;
  6. Set Update Mode to Animate Physics.

Setting up the *Animator Controller* on the *TutorialPlayer*
Setting up the Animator Controller on the TutorialPlayer.

When the animator controller is connected, double-click on it to open the unity animator editor.

*Animator Editor* with our *Animator Controller* open
Animator Editor with our Animator Controller open.

Available parameters used by the animator controller
Available parameters used by the animator controller.

To explore the available parameters, click on the Parameters tab. Here you can see several parameters, but for now we are only going to use MoveZ, MoveX and Jump. MoveZ and MoveX are floats and Jump is a trigger. Go to the Window/Bolt/Assets window and open up the TutorialPlayerState we created earlier.

*TutorialPlayerState* editor
TutorialPlayerState editor.

We are going to define three new properties here, called the same thing as the three ones from the mecanim animator we are using.

  • MoveX, Float
  • MoveZ, Float
  • Jump, Trigger

In the settings for each property, switch the mecanim setting from Disabled to Parameter.

*TutorialPlayerState* editor with properties to use with the animation system
TutorialPlayerState editor with properties to use with the animation system.

There is one more option we need configure, to the right of the Disabled/Parameter/Layer Weight selector for mecanim you also have the option of selecting between Use Animator Methods and Use Bolt Properties.

  • Use Animator Methods means that you want to use the normal SetFloat, SetInteger, etc. methods of mecanim and have Bolt automatically pull the value out.
  • Use Bolt Parameters means that you want to use the Bolt parameters to set the mecanim values and have Bolt apply them to mecanim for you.

You can also configure this state wide at the top in the state specific settings. We are going to select Use Bolt Properties on MoveZ, MoveX and Jump.

We are almost done, it's time to compile Bolt again, go to Assets/Bolt/Compile Assembly and let Bolt do it's thing. Now open up the TutorialPlayerController.cs script.

We are going to add a new method called AnimatePlayer, its pretty much standard mecanim code where we set a MoveZ parameter to -1 or +1 depending on if we are moving forward/backward and the same with MoveX for left/right.

    void AnimatePlayer(TutorialPlayerCommand cmd)
    {
        // FWD <> BWD movement
        if (cmd.Input.Forward ^ cmd.Input.Backward)
        {
            state.MoveZ = cmd.Input.Forward ? 1 : -1;
        }
        else
        {
            state.MoveZ = 0;
        }

        // LEFT <> RIGHT movement
        if (cmd.Input.Left ^ cmd.Input.Right)
        {
            state.MoveX = cmd.Input.Right ? 1 : -1;
        }
        else
        {
            state.MoveX = 0;
        }

        // JUMP
        if (_motor.jumpStartedThisFrame)
        {
            state.Jump();
        }
    }

Inside of the ExecuteCommand function we are going to call our new AnimatePlayer function, we are going to access a very specific property on our command called IsFirstExecution. If this is true that means that this is the first time this command is being executed, in that case we want to apply our animations.

    public override void ExecuteCommand(Bolt.Command command, bool resetState)
    {
        TutorialPlayerCommand cmd = (TutorialPlayerCommand)command;

        if (resetState)
        {
            // we got a correction from the server, reset (this only runs on the client)
            _motor.SetState(cmd.Result.Position, cmd.Result.Velocity, cmd.Result.IsGrounded, cmd.Result.JumpFrames);
        }
        else
        {
            // apply movement (this runs on both server and client)
            PlayerMotor.State motorState = _motor.Move(cmd.Input.Forward, cmd.Input.Backward, cmd.Input.Left, cmd.Input.Right, cmd.Input.Jump, cmd.Input.Yaw);

            // copy the motor state to the commands result (this gets sent back to the client)
            cmd.Result.Position = motorState.position;
            cmd.Result.Velocity = motorState.velocity;
            cmd.Result.IsGrounded = motorState.isGrounded;
            cmd.Result.JumpFrames = motorState.jumpFrames;

            // NEW CODE
            if (cmd.IsFirstExecution)
            {
                AnimatePlayer(cmd);
            }
        }
    }

The last thing we need to do is to pass in the correct animator to Bolt, we will do this inside the Attached callback where we are setting our transform:

  public override void Attached() 
  {
    state.SetTransforms(state.Transform, transform);
    state.SetAnimator(GetComponentInChildren<Animator>());

    // Configure Animator
    state.Animator.SetLayerWeight(0, 1);
    state.Animator.SetLayerWeight(1, 1);
  }

You can start the game and run around with our character now, you can choose to just Play As Server or also connect clients if you want.

Next Chapter >>

 To Document Top