Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*

.idea
src/guides/.idea
src/.vuepress/.idea

# builds
dist/
tsconfig.tsbuildinfo
15,100 changes: 9,294 additions & 5,806 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
"watch": "vuepress watch ./src",
"dev": "vuepress dev ./src"
},
"dependencies": {},
"devDependencies": {
"markdown-it-html5-embed": "^1.0.0",
"vuepress": "^1.9.7"
"vuepress": "^1.9.10"
}
}
1 change: 1 addition & 0 deletions src/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ module.exports = {
sidebarDepth: 2,
children: [
'/guides/creating-a-player-controller',
'/guides/creating-a-finalik-player',
'/guides/upgrading-from-normcore-1-to-normcore-2',
{
title: 'Recipes',
Expand Down
129 changes: 129 additions & 0 deletions src/guides/creating-a-finalik-player.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
layout: docs
title: Creating a FinalIK Player Controller
---
# Creating a FinalIK Player Controller

This guide will demonstrate how to create a multiplayer third-person character controller that uses models and animations from the FinalIK package.

When you're finished, you'll end up with multiplayer characters that look like this:

![](./creating-a-finalik-player/completed-character-controller.mp4)

We will start by creating a single-player variant of the character controller, complete with a follow camera, and a FinalIK model with clean animation and controls.

## Creating a singleplayer player controller

We are going to need a scene to get started. Create a copy of the Blank Scene Template scene included in the `Normal/Examples/Blank Scene Template` folder. Save it as "FinalIK Player Controller".

Create an empty game object in the scene named "Player". Reset the Transform to center the object.

Add a **Rigidbody** to the Player game object so that it can respond to physics. We'll always want our player to remain upright, so let's enable Freeze Rotation on every axis.

Last, we'll add a Capsule game object to represent the body of the player. Set the y-position at 1 so the bottom is lined up with the ground.

![](./creating-a-finalik-player/adding-player-object.mp4)

Looking good so far! If we enter Play mode, nothing will happen, so let's Add in some Player controls.

### Adding Player Controls

On the Player object, add the "Player" component.

With that added, we can now enter play mode, and test out the controls. Using WASD, you should see the capsule move around and jump with Space.

![](./creating-a-finalik-player/adding-player-controls.mp4)

So far so good, but we don't just want to play as a capsule. Let's fix that.

### Using a FinalIK Model

With the FinalIK package added to our project, we have access to a handful of models that work great with our guide.

Navigate to the `Plugins/RootMotion/Shared Demo Assets/Characters` folder, and select a biped model that you would like to use. Drag and drop the model as a child of your Player object.

Now we can hide the capsule that is blocking the model. Select the capsule component, and disable the Mesh Renderer component.

![](./creating-a-finalik-player/adding-finalik-model.mp4)

Next, we need to change the animator controller reference that is on the FinalIK character to our animator controller called "FinalIKPlayerAnimatorController".

Drag in a reference to our new character into our Player script.

![](./creating-a-finalik-player/adding-character-reference.mp4)

With that reference set, we can now give it another test!

![](./creating-a-finalik-player/testing-finalik-model.mp4)

The new model and animations look good, but there are still a handful of FinalIK components that we can use to polish the animations further.

### Using FinalIK Components

FinalIK offers a variety of components that work together to polish up animations for specific needs within your game. Many more components can be used to suit your specific needs, but for this guide, we will be using a few components to add inverse kinematics to the feet and tilt to the body.

On your FinalIK character add a new component called "Full Body Biped IK".

Add another component called "BodyTilt". Make sure you drag in a reference to the Full Body Biped IK component, as well as the tilt poses that we have provided in the `Normal/Examples/FinalIK Player/ FinalIK Character` folder. You can adjust the values for Tilt Speed, and Tilt Sensitivity as you like, but we have found 5.0 for Tilt Speed and 0.2 for Tilt Sensitivity look great.

![](./creating-a-finalik-player/adding-body-tilt.mp4)

Let's add another component called "GrounderFullBodyBiped". Open up the Solver, and set the Layers to "Default". This will be the layer that foot collisions will happen on, so make sure it matches the layer that any ground colliders will be on for your game.

![](./creating-a-finalik-player/adding-grounder.mp4)

With that last change, we are ready to test our new animations.

![](./creating-a-finalik-player/testing-finalik-animations.mp4)

When testing try standing still on top of the small blocks within the scene, you should see the feet rotate to match the ground below.

Now that the character looks great, we can address the camera. Up to this point in the guide the camera has been stuck in one place, so let's fix that!

### Adding Follow Camera and Camera Controls

Add a new component to our Player object called "CameraManager". This will handle all of the camera-related movement and controls for our third-person player.

Create an empty game object as a child of our Player object, named "Follow Target". Then position this object at { 0, 1, 0 }. This will be used to keep the rotation of our camera separate from the rotation of our character model.

Now we need to add the "Follow Target" object as a reference to our CameraManager script.

Add the CameraManager reference to our Player script.

![](./creating-a-finalik-player/adding-camera-controls.mp4)

Now we can hit PLAY and test our new follow camera.

![](./creating-a-finalik-player/testing-camera-controls.mp4)

When testing you will see that the camera follows us around, and can be rotated using the mouse. This feels great, but our player is still stuck in single-player, let's fix that by making this multiplayer!

### Making it Multiplayer

There are two parts to making our player multiplayer. The first part is to track the transformation of our player and associated objects over the network.

Luckily Normcore has a few built-in components to make this step easy. To track the transformation of an object over the network using Normcore, we just need to add a RealtimeTransfrom component to that object.

Add a "RealtimeTransformManager" component to our player object. This will ensure that our player has ownership of all of the Realtime components we just added.

Go ahead and add a RealtimeTransform component to our Player object. This will also add a RealtimeView component, which is used by Normcore to track the ownership of an object over the network. Within the RealtimeTransfrom component, make sure that "Sleep" is set to "Maintain Ownership While Sleeping".

Add another RealtimeTransform component to our FinalIK character.

![](./creating-a-finalik-player/adding-realtime-components.mp4)

Now our Player is complete, and we can turn it into a prefab by dragging and dropping it into the "Resources" folder. Then we can delete it from the scene.

![](./creating-a-finalik-player/creating-player-prefab.mp4)

Next, we need to create an empty game object called "Player Manager" and add the PlayerManager component to it. This will allow us to connect and play with other players over the network.

Drag in our newly created Player prefab as a reference in our PlayerManager script. This is the player that will be spawned for us.

Lastly, we need to add a "Realtime" component to our player manager object. Set the "App Settings" and paste in the appID.

![](./creating-a-finalik-player/adding-player-manager.mp4)

If you want to test this quickly, you can go to `File/Build And Run` and create the first instance of the game. Then use the Play button in the editor to connect as a second player. Each of these players will be synced and playable in multiplayer!

![](./creating-a-finalik-player/final-test.mp4)
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
107 changes: 107 additions & 0 deletions src/guides/using-final-ik.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
layout: docs
title: Using Final IK
---
# Using Final IK

Final IK is the most popular Unity asset for adding realistic IK to player controllers in your game. This guide will demonstrate how to create a multiplayer player controller in Normcore using Final IK.

When you're finished, you'll end up with a multiplayer game that looks like this:

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

We'll start by creating a singleplayer player controller from scratch with Final IK. (TODO: Rewrite the next sentence once the guide is complete) We'll get the controls to feel nice, and then we'll make it multiplayer. If you're only interested in the multiplayer part, skip to [making it multiplayer](#making-it-multiplayer).

## Creating a player controller

Before we can utilize Final IK, we'll need a player controller that allows us to move the player with WASD keys. Create a copy of the Blank Scene Template scene included in the `Normal/Examples` folder. Save it as "Final IK Player Controller".

Let's start by creating a game object to represent the player. Create an empty game object in the scene named "Player" and add Normcore's built-in **Player** component.

Add a **Rigidbody** to the "Player" game object so that it can respond to physics. We'll always want our player to remain upright, so let's enable Freeze Rotation on every axis.

Last, we'll add a Capsule game object to represent the body of the player. Set the y-position at 1 so the bottom is lined up with the ground.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

Looking good so far! If we enter Play mode, we can use the WASD keys to move our capsule player around.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

## Integrating a Final IK character

Now that we have a player controller that we can move around, it's time to bring in a Final IK character. First, if you haven't already, import Final IK from the asset store.

Grab a Final IK character from the `Plugins/RootMotion/Shared Demo Assets/Characters` folder and drag it into the scene as a child of the "Player" game object. In this example, we'll be using the Pilot.

Last but not least, let's hide the **MeshRenderer** for the capsule collider. It's important to keep the collider itself enabled so our player doesn't fall through the ground.

Let's enter play mode and try this out.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

As we can see, our character is there, but (TODO: how does it fail?). In order for our character to animate correctly, we'll need to set up an animation controller.

Normcore comes with a built-in animation controller for Final IK. Drag the **PlayerAnimatorController** component from the Unity project into the **Controller** field on the **Animator** component. And to ensure that the **Player** component can drive this animator controller, drag a reference from the "Pilot" game object into the **Character** slot.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

Much better! This looks good, but Final IK provides a handful of built-in components that we can use to polish this animation even further.

## Using Final IK components

Our character works well, but there are a few places where it falls short. Our character doesn't lean when running in a circle, and if we add a ramp to the scene that our character can walk up, you can see the character's feet don't line up with the ground.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

Luckily, Final IK comes with a variety of components that can be used to refine the animation of our character.

On the "Pilot" game object, add a **FullBodyBipedIK** component, a **BodyTilt** component.

Populate the **BodyTilt** component **IK** field by dragging in a reference to the **FullBodyBipedIK** component. We'll also need to provide a left and right pose. Normcore includes a "Pose Left" and "Pose Right" preset that can be found in the `Normal/Examples/Final IK Player Controller/Character` folder.

You can adjust the values for **Tilt Speed**, and **Tilt Sensitivity** as you like, but we have found 5.0 for Tilt Speed and 0.2 for Tilt Sensitivity look great.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

Last, let's add the **GrounderFullBodyBiped** component. Open up the Solver, and set *Layers* to "Default". This is the collision layer used for the solver. As your game grows, you may want to create a dedicated layer for the ground and surfaces you would like your player to land on.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

Now that both of those components are set up. Let's test it out! Have the player run in a circle and walk up the ramp.

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Ideally this video is a frame by frame replay of the first video where it didn't work, but now it works)

Much better! Our character now runs around and looks great doing it, but our camera is left behind. Let's fix that!

## Camera controls

Normcore comes with a built-in component called **PlayerCameraManager**. This component handles all of the logic for moving the camera with your player. It also supplies metadata about where the camera is looking so the **Player** component can correctly handle things like strafing.

Add the **PlayerCameraManager** component to the "Player" game object and create a child game object called "Follow Target". This will represent the point on the player that the camera should follow. Wire it up to the **Follow Target** slot and we're good to go. (TODO: Player should automatically find the **PlayerCameraManager** component if the're on the same game object)

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)

Let's test it out! Our camera should now smoothly follow the player and we can use the mouse to adjust the look direction and our player will follow suit!

<video src="./creating-a-player-controller/sphere-player-mouse-jump-6.mp4" width="100%" controls></video>
(Video demonstrating the steps above)


### Making it Multiplayer

At this point, we've got a Final IK player controller that looks great, and a camera that follows our player. Now we'll use Normcore to make it work in multiplayer.

(TODO: Do we build the RealtimeTransformManager component into Normcore or does this exist in RealtimeView?)

Blocked on the above TODO, will write the rest once we know how this manifests in Normcore.