mechanic animations - appspot.combranko-cirovic.appspot.com/cp3830/unity3d.mecanim.pdf · mechanic...

Post on 20-Mar-2020

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Mechanic Animations

Mecanim is Unity's animation state machine system.

It essentially allows you to create 'states' that play animations and define transition logic.

Create new project Animation demo.

AssetsDrag and drop provided folders (Animations, Characters) as well as Tile.jpg into Assets.

AnimationsSelect animation folder, animation of your choice and observe behaviour in Inspector panel.

Character Setup

From Assets > Characters select Beta@Beta and in Inspector set Rig tab, Animation Type: Humanoid

Character SetupIn Project panel, Assets right-click create new Animation Controller.

Similarly, create new C# script, name ControllerScript.

Save scene as Scene_0.

Character SetupAdd character to the scene (0, 0, 0)

Character Setup

With the character in the scene selected, use the Inspector to assign the animator controller.

Simply drag it from assets into Animator Controller field.

Creating Prefab

Create prefab by adding a new empty game object (Player Prefab) in Hierarchy.

Drag character Beta@Beta into Player Prefab. For the basic follow add Main Camera to Prefab as well (0, 1.4, -2), (13, 0, 0).

Also add plane to the scene

Set plane position to (0, 0, 0) and scale to (10, 1, 10).

Drag tile from assets into the plane and set tiling to (100, 100) in Inspector, Tile, Main Maps.

Creating Prefab

Creating Prefab

Select character (Beta) and copy Animator component (settings icon on the right, copy component).

Select prefab and paste component as new.

Back to character and remove Animator Controller.

Creating PrefabAdd Controller Script to prefab (Add Component, New Script, ControllerScript - one we created earlier).

Select prefab, in Inspector, Add Component > Physics > Character Controller.

Transformation values might need adjustment.

Also, make sure that Apply Root Motion is checked.

Creating PrefabCharacter and prefab are positioned at (0, 0, 0). Set Character Controller’s parameters as:

Creating PrefabFinally, to create prefab, drag Player Prefab from Hierarchy to Project

AnimationsCreating an Idle/Walk with a Blendtree

In the Animator window right-click anywhere on the grid and select "Create > From New Blendtree"

AnimationsThis creates a new state and assigns it to be the default state.

The default state is always in orange and will be the state that your animation starts out in.

Double click on the state to view the blend tree.

AnimationsIn order to control this blend tree, we'll need a new parameter.

In the top-left of the Animator Window select the + button in the Parameters tab and create a new Float parameter and name it VSpeed

AnimationsBack in the Animator, double click IdleWalk state. Set Parameter to VSpeed.

Click the plus button and from Assets, Animations folder, drag Idle animation into the Motion field.

AnimationsRepeat the process and drag walking animation into the second Animation field.

Blend tree and associated inspector should look like:

ScriptingIn order to control switching from one state to the other we need to write C# script.

Up arrow key down will switch from idle to walking state and up arrow key up will switch from walking to idle state.

Open ControllerScript.cs from Assets panel or Player Prefab.

Scriptingusing UnityEngine; using System.Collections;

public class BehaviourScript : MonoBehaviour {

private Animator myAnimator; void Start () { myAnimator = GetComponent<Animator>(); }

void Update () { myAnimator.SetFloat ("VSpeed", Input.GetAxis ("Vertical")); } }

It’s alive!

Transitions between states based on parameter

Transitions between animations can be based on parameter.

In animator/parameters add another parameter - HSpeed

Left/Right strafe animations

Transitions between states based on parameter

Animations can be dragged directly from our project window onto the animator grid to create a new state:

Transitions between states based on parameter

To create the actual transition right-click on IdleWalk state (make transition) and connect it to left_strafe state:

Transitions between states based on parameter

Each transition has rules for when it is allowed to occur.

The default transition is 'exit time'.  That means that as soon as the current animation is done playing, it will transition into the next.

We don't want to automatically transition, so instead we're going to transition based on our HSpeed parameter.

Transitions between states based on parameterClick on the transition arrow and the inspector will show some additional information.

Towards the bottom you'll see an area called Conditions.  

Change the condition from Blend time to "HSpeed".  

Transitions between states based on parameter

For this particular transition we want HSpeed to be less than -0.1 because GetAxis uses -1 as Left, 0 as neutral and 1 as right.

Also uncheck Has Exit Time and Fixed Duration.

In order to return to IdleWalk state we need a transition from left_strafe to IdleWalk

Transitions between states based on parameter

For this particular transition we want HSpeed to be less than -0.1 because GetAxis uses -1 as Left, 0 as neutral and 1 as right.

Also uncheck Has Exit Time and Fixed Duration.

In order to return to IdleWalk state we need a transition from left_strafe to IdleWalk

Transitions between states based on parameter

As before, add new condition based on HSpeed being greater than -0.1 and uncheck Has Exit Time and Fixed Duration

Transitions to/from right_strafe are similar:

IdleWalk to right_strafe: HSpeed > 0.1right_strafe to IdleWalk: HSpeed < 0.1

Script

In order to with from IdleWalk/left-right strafe we need a single line of code in our existing script:

myAnimator.SetFloat("HSpeed", Input.GetAxis("Horizontal"));

It’s alive!

Any State

Any animation that transitions from Any State is essentially transitioning from ALL states.

We'll create a jump animation that lets the character jump whether idling, walking or strafing.

Any StateFirst, drag the jump animation onto the Animator grid to create a new jump state.

We also need a new parameter.  This time we'll use a boolean called "Jumping".

Any State

Any State

We want to transition from Any State when Jumping is true.

Create a transition between Any State and jump and use the Inspector to change the condition from "Blend" to "Jumping" is true.

Uncheck Has Exit Time, but leave Fixed duration.

Any StateWe also need to transition out of jumping back to the IdleWalk blendtree.

Create a transition from jump to IdleWalk and leave the condition to exit time.

This is because we want to exit jump as soon as the jump animation is over.

Any State

Script

The last thing to do is add the jump controls to our script. This is done in a few steps.

First, we need to listen for input (spacebar):

if(Input.GetButtonDown ("Jump")){ myAnimator.SetBool ("Jumping", true); Invoke ("StopJumping", 0.1f); }

Script

StopJumping() method simply sets boolean variable Jumping to false:

void StopJumping(){ myAnimator.SetBool ("Jumping", false); }

It’s alive and jumping!

Conditions to InputYou can combine conditions in your script with conditions in your animator to create animations that will fire only under very specific conditions.

For example, we have some turning animations but they are 'in place' turning, so we only want to use it if the character is standing still.

Conditions to Input

First, let's add the animations to the animator as two new states - left_turn and right_turn and add two new conditions.

We'll make these boolean parameters, called TurningLeft and TurningRight.

Conditions to Input

Conditions to InputNext, let's create our transitions.

We want to transition to turn left only if we are currently standing still (so it has to be from IdleWalk) and only if turning left is true.

When it's false, we'll go back to IdleWalk. Same for turning right. 

Conditions to Input

IdleWalk -> left_turn

Condition: TurningLeft = true

Has Exit Time: unchecked

Fixed Duration: unchecked

left_turn -> IdleWalk

Condition: TurningLeft = false

Has Exit Time: unchecked

Fixed Duration: unchecked

IdleWalk -> right_turn

Condition: TurningRight = true

Has Exit Time: unchecked

Fixed Duration: unchecked

IdleWalk -> right_turn

Condition: TurningRight = false

Has Exit Time: unchecked

Fixed Duration: unchecked

Back in our script, we now need to listen for some additional input.

We are going to manually assign the Input to be the Q and E keys.

When those buttons are pressed and released, we'll toggle TurningLeft and TurningRight respectively to be true and false.

Conditions to Input

Scriptif(Input.GetKey(“q")) { if((Input.GetAxis ("Vertical") == 0f) && (Input.GetAxis ("Horizontal") == 0)){ myAnimator.SetBool ("TurningLeft", true); } } else { myAnimator.SetBool ("TurningLeft", false); } if(Input.GetKey("e")){ if((Input.GetAxis ("Vertical") == 0f) && (Input.GetAxis ("Horizontal") == 0)){ myAnimator.SetBool ("TurningRight", true); } } else { myAnimator.SetBool ("TurningRight", false); }

Procedural MotionOur player is really NOT turning around when we press Q or E keys.

These particular turns don't include 'root motion’.

So far all of our character movement has been handled completely by the animations driving the game object.

Procedural MotionThere may be times our animation doesn't have root motion or we specifically want to control the motion of the character through code.

We're going to add a procedural turn to our character that will let them actually turn while the turn animation is playing AND allow them to turn while walking/running.

Script

if(Input.GetKey("q")){ transform.Rotate (Vector3.down * Time.deltaTime * 100.0f); if((Input.GetAxis ("Vertical") == 0f) && (Input.GetAxis ("Horizontal") == 0)){ myAnimator.SetBool ("TurningLeft", true); } } else { myAnimator.SetBool ("TurningLeft", false); }

Script

if(Input.GetKey("e")){ transform.Rotate (Vector3.up * Time.deltaTime * 100.0f); if((Input.GetAxis ("Vertical") == 0f) && (Input.GetAxis ("Horizontal") == 0)){ myAnimator.SetBool ("TurningRight", true); } } else { myAnimator.SetBool ("TurningRight", false); }

It’s alive!

Sub state machinesSometimes we may have completely separate animation sets that we want to have their own animation logic.

Sub State Machines let us create a new grid area with it's own logic.

We're going to use a sub state machine to add a few actions to our character (Kneel down, kneel up, dance)

Sub state machinesTo create a sub state machine right-click anywhere on the animator grid and select "Create Sub State Machine".

In the inspector, give the sub state machine a name (“Actions”).

Sub State machines are represented by a hexagonal state.

Sub state machines

Sub state machines

We also want to create a new parameter - “CurrentAction” of type int each action in the actions state machine.

Double click on the Sub State Machine to enter the sub state.

Here, we're going to create a new state by dragging our gangnam style dance into the grid.

Sub state machines

Sub state machines

To create a transition to a state inside a Sub State Machine, right-click on the state you want to transition from, select Make Transition and then click on the Sub State Machine.

From the list, select the state you want to transition into.

Sub state machines

Sub state machines

In order to transition OUT of the dance state, we have to set CurrentAction to 0.

Uncheck Has Exit Time and Fixed Duration.

Sub state machines

In order to transition TO dance state, go back to Animator Base Layer, right-click IdleWalk, Make Transition, connect to Actions.

Here select state gangnam_style_24.

Sub state machines

Sub state machines

In order to transition INTO the dance state, we have to set CurrentAction to 1.

Uncheck Has Exit Time and Fixed Duration.

Sub state machines

Script

if(Input.GetKeyDown ("1")) { if(myAnimator.GetInteger("CurrentAction") == 0) { myAnimator.SetInteger("CurrentAction", 1); } else if (myAnimator.GetInteger ("CurrentAction") == 1) { myAnimator.SetInteger ("CurrentAction", 0); } }

It’s alive and dancing!

Combining techniques

We're going to combine several of the previous ideas to create a kneeling toggle.

This will use a 3 part animation, the idea of toggles, conditional transitions, exit time transitions, and the integer based index of actions.

Combining techniques

First, let's add all three animations to the Actions Sub State Machine as three new states.

These are kneeling_down, kneeling idle and kneeling_stand.

Combining techniques

Combining techniques

We're going to transition from IdleWalk on the base layer into kneeling_down when CurrentAction is equal to 2.

Combining techniques

Back in Actions, we need the following transitions:

• kneeling_down to kneeling_idle on Exit Time

• kneeling_idle to kneeling_stand if CurrentAction is 0

• kneeling_stand to IdleWalk on Exit Time

Combining techniques

Transitions

Script

if(Input.GetKeyDown ("2")){ if(myAnimator.GetInteger ("CurrentAction") == 0) { myAnimator.SetInteger ("CurrentAction", 2); } else if (myAnimator.GetInteger ("CurrentAction") == 2) { myAnimator.SetInteger ("CurrentAction", 0); } }

It’s alive!

Animation Layers

It is possible to have multiple layers of animation that affect the layers beneath them.

We're going to use a layer to create a wave animation that only plays on the upper body and can be played any time, overriding any animation on the base layer.

Animation LayersThe first thing we'll need is an avatar mask.

You can create an avatar mask using "Assets > Create >Avatar Mask”

Call it “UpperBodyMask”

Animation LayersSelect avatar mask and using inspector deselect legs, left arm and hand.

Select ground and four IKs.

Animation LayersBack in the Animator, create a new Layer - “UpperBody”.

In UpperBody Layer’s settings, set mask to UpperBodyMask and blending to Override.

Animation Layers

The new layer has an empty state machine.

Let's create an empty state by right-clicking the grid and selecting "Create State > Empty" and name it Empty.

Let's also drag our wave animation into the grid.

Animation Layers

The reason for having an empty animation is because sometimes we need a way for this layer to not be playing the wave animation.

Animation LayersWe'll use our actions indexing integer so we want to transition to the wave animation when CurrentAction is 3.

The wave isn't looping, so we'll transition out based on exit time.

• From Empty to wave if CurrentAction is 3

• From wave to Empty on Exit Time

Animation Layers

Transitions

Script

if(Input.GetKeyDown ("3")){ myAnimator.SetLayerWeight (1, 1f); myAnimator.SetInteger("CurrentAction", 3); } if(Input.GetKeyUp ("3")){ myAnimator.SetInteger ("CurrentAction", 0); }

It’s alive!

PhysicsNow that we have our character rigged, let’s see how it interacts with the environment.

Create a new scene, add plane (scale 10, 1, 10 at 0, 0, 0, grass textured tiling 50, 50)

Add cube ((0, 0, 5), (45, 0, 0), (3, 3, 3), stone texture tiling 2, 2)

Finally, add Player prefab at 0, 0, 0.

Physics

Physics

So, we can climb slope, assuming angle is less than or equal to 45.

How about moving things around? Add couple of more cubes (scale 0.25, 1.5, 0.25).

Place the second one on top of the first one.

Physics

PhysicsWe can’t move newly added blocks - we need to add rigid bodies to them.

No luck. In order to have our player interact with the environment we need to create a Ragdoll.

Physics

From the hierarchy, unfold character Beta@Beta as shown:

Physics

Now, create new game object, 3D object, Ragdoll and character’s bones from hierarchy into appropriate slots:

Physics

This process turns each part of character’s body into a rigid object.

By selecting each part from the hierarchy, you can change default parameters in Inspector.

PhysicsIf you play now, you should be able to move rigid objects around.

Shoot

We can interact with the environment directly, but not yet indirectly.

In our next example, we’ll shoot cannonballs (or flower bouquets if you prefer) at objects.

Create new project “Shoot”. Create several objects and assign rigid bodies to them.

Shoot

Camera

The shooter will be our camera ((0, 3, 8), (0, 180, 0))

In order to orbit as well as tilt our camera, we need a C# script Cannon.cs

Cannon.csusing UnityEngine; using System.Collections;

public class Cannon : MonoBehaviour { void Start () {}

void Update () { float x = Input.GetAxis("Mouse X") * 2; float y = -Input.GetAxis("Mouse Y"); // vertical tilting float yClamped = transform.eulerAngles.x + y; transform.rotation = Quaternion.Euler(yClamped, transform.eulerAngles.y, transform.eulerAngles.z); // horizontal orbiting transform.RotateAround(new Vector3(0, 3, 0), Vector3.up, x); } }

CannonballSelect camera, add component C# script and attach Cannon.cs

In order to shoot cannonballs, we need a cannonball.

Create a sphere scaled to (0.5, 0.5, 0.5), assign rigid body and drag it from Hierarchy to Assets.

CannonballBack to our Cannon.cs, declare GameObject:

public GameObject Cannonball;

In order to shoot cannonballs, we need a method:void FixedUpdate () { if (Input.GetButtonDown("Fire1")) { GameObject projectile = Instantiate(Cannonball, transform.position, transform.rotation) as GameObject; projectile.GetComponent<Rigidbody>(). AddRelativeForce(new Vector3(20, 20, 2000)); } }

Shoot

CannonballObserve, in Hierarchy, the number of cloned cannonballs as we shoot:

Even if the cannonball falls of the edge, it will continue to exist as long as the game keeps running and its physics will continue to be calculated, eventually slowing things down.

BoundaryIn order to prevent this, we need to create a boundary and destroy cannonball when it collides with it.

Create new Game Object, Empty, rename it to Boundary, position at (0, 0, 0).

Add Component, physics, Box Collider. Set it as trigger and position it at:

Boundary

BoundaryNow we have to write a script, Boundary.cs, that will destroy any object colliding with the boundary.

using UnityEngine; using System.Collections;

public class Boundary : MonoBehaviour { void Start () {} void Update () {}

void OnTriggerExit(Collider other) { Destroy(other.gameObject); } }

Boundary

If you only want to destroy cannonballs, modify onTriggerExit method:

void OnTriggerExit(Collider other) { if(other.gameObject.name == "Cannonball(Clone)") { Destroy(other.gameObject); } }

Shooting at characters

First of all, let’s import our character with animations from the asset store: https://www.assetstore.unity3d.com/en/#!/content/5330

Or in asset store, Animation > Bipedal > Raw Mobcap Data for Mecanim

Shooting at characters

Shooting at charactersImport asset and drag avatar into the scene.

Shooting at charactersRecall that we have to turn character into a rag doll in order to interact with objects.

Drag appropriate bones into Ragdoll’s dialogue.

Shooting at characters

If you play the game now, observe that ragdoll collapses instantly.

It does respond to cannonballs, but we want it to stand initially and only when hit to turn into a ragdoll.

Shooting at charactersFor that, we need an animator. So, in project, create new animator controller.

Open controller, and from Assets > Raw Mocap Data > Animations > Idle, drag Idle_Ready into Animator.

Shooting at characters

If you play it now, Avatar want collapse, cannonballs bounce of it when hit.

How to have the character collapse when hit?

Before we proceed, in Project panel, create prefab named Ragdoll and drag DefaultAvatar into it.

Shooting at charactersYou can now delete DefaultAvatar from the Hierarchy and add Ragdoll prefab to the scene.

Collision can occur between two colliders, one of them being a cannonball.

In order to detect collision between cannonball and anything else we need a script.

CannonballCollider.csusing UnityEngine; using System.Collections;

public class CannonballCollider : MonoBehaviour { void Start () {} void Update () {}

void OnCollisionEnter (Collision col) { Debug.Log ("Cannonball hit something" + col.gameObject.name); } }

Shooting at characters

Script, of course, needs to be attached to a Cannonball prefab.

Rather than detecting collision with each and every bone in our ragdoll, we can add the tag.

Select Ragdoll and in Inspector create a new tag “ragdollBones”

Shooting at charactersNow, to each and every bone that constitutes our Ragdoll, assign this new tag “ragdollBones”.

We need to modify our script as well:

void OnCollisionEnter (Collision col) { if(col.gameObject.tag == "ragdollBones") Debug.Log("Ragdoll hit"); }

Shooting at characters

The last thing required is for the cannonball to send message to ragdoll prefab, in order to collapse.

For this, first of all, we need a new script “RagdollController.cs”

RagdollController.csusing UnityEngine; using System.Collections;

public class RagdollController : MonoBehaviour { private Animator anim; void Start () { anim = GetComponent<Animator> (); }

void Update () {} void killRagdoll () { anim.enabled = false; } }

Shooting at characters

What remains is to send message “killRagdoll” from CannonballController on collision:

void OnCollisionEnter (Collision col) { if(col.gameObject.tag == "ragdollBones") { GameObject.Find(“Ragdoll"). SendMessage("killRagdoll"); } }

Joints

Physics joints in Unity are used to connect (join) two rigid bodies.

Here, we’ll take a look at fixed, hinge and spring joints.

Fixed Joint

Fixed Joints restricts an object’s movement to be dependent upon another object.

This is somewhat similar to Parenting but is implemented through physics rather than Transform hierarchy.

Fixed Joint

Property DescriptionConnected body Optional reference to the Rigidbody that the joint is dependent upon. If not

set, the joint connects to the world.

Break force The force that needs to be applied for this joint to break.

Break torque The torque that needs to be applied for this joint to break.

Enable Collision When checked, this enables collisions between bodies connected with a joint.

Enable Disabling preprocessing helps to stabilize impossible-to-fulfil configurations.

Hinge Joint

The Hinge Joint groups together two Rigidbodies, constraining them to move like they are connected by a hinge.

It is perfect for doors, but can also be used to model chains, pendulums, etc.

Hinge Joint

Hinge JointProperty Description

Connected body Optional reference to the Rigidbody that the joint is dependent upon. If not set, the joint connects to the world.

Anchor The position of the axis around which the body swings. The position is defined in local space.

Axis The direction of the axis around which the body swings. The direction is defined in local space.

Auto Configure Connected Anchor

If this is enabled, then the Connected Anchor position will be calculated automatically to match the global position of the anchor property.

Connected Anchor Manual configuration of the connected anchor position.

Hinge JointProperty Description

Spring Properties of the Spring that are used if Use Spring is enabled.

Spring The force the object asserts to move into the position.

Demper The higher this value, the more the object will slow down.

Target position Target angle of the spring. The spring pulls towards this angle measured in degrees.

Use motor The motor makes the object spin around.

Hinge JointProperty Description

Motor Properties of the Motor that are used if Use Motor is enabled.

Target velocity The speed the object tries to attain.

Force The force applied in order to attain the speed.

Free Spin If enabled, the motor is never used to brake the spinning, only accelerate it.

Use limitsIf enabled, the angle of the hinge will be restricted within the Min & Max values.

Hinge JointProperty Description

Limits Properties of the Limits that are used if Use Limits is enabled.

Min The lowest angle the rotation can go.

Max The highest angle the rotation can go.

Bounciness How much the object bounces when it hits the minimum or maximum stop limit.

Contact Distance Within the contact distance from the limit contacts will persist in order to avoid jitter.

Property Description

Break force The force that needs to be applied for this joint to break.

Break torque The torque that needs to be applied for this joint to break.

Enable Collision When checked, this enables collisions between bodies connected with a joint.

Enable Disabling preprocessing helps to stabilize impossible-to-fulfil configurations.

Hinge Joint

Spring Joint

The Spring Joint joins two Rigidbodies together but allows the distance between them to change as though they were connected by a spring.

Spring Joint

Spring JointProperty Description

Connected body Optional reference to the Rigidbody that the joint is dependent upon. If not set, the joint connects to the world.

Anchor The point in the object’s local space at which the joint is attached.

Auto Configure Connected Anchor

Should Unity calculate the position of the connected anchor point automatically?

Connected Anchor The point in the connected object’s local space at which the joint is attached.

Spring Strength of the spring.

Demper Amount that the spring is reduced when active.

Spring JointProperty Description

Min distance Lower limit of the distance range over which the spring will not apply any force.

Max distance Upper limit of the distance range over which the spring will not apply any force.

Tolerance Changes error tolerance. Allows the spring to have a different rest length.

Break force The force that needs to be applied for this joint to break.

Break torque The torque that needs to be applied for this joint to break.

Enable Collision Should the two connected objects register collisions with each other?

Enable Disabling preprocessing helps to stabilize impossible-to-fulfil configurations.

ExampleWe’ll continue with our previous project (Shoot).

Let’s create a wracking ball first it consists of a sphere and 4 scaled capsules (0.15, 0.25, 0.15) appropriately positioned.

All of the objects must have RigidBody component.

ExampleSelect the sphere, add component HingeJoint and drag the first link from Hierarchy into the Connected Bodycomponent.

Example

Continue this process: connect link1 to link2, link2 to link3 and link3 to link4 using Hinge Joint.

In order to have our wracking ball hanging in the air, we need to add Fixed Joint to the last link - no need to connect it to anything.

Shoot!

Example

Similarly, create five spheres and connect them in bottom-up fashion using Spring Joint.

The sphere on top should have the Fixed Joint component.

Shoot!

top related