Now that your animated character is ready, you might want to coordinate his actions with his animation states. In this recipe, we will exemplify this by making the character throw an object when the player presses the appropriate button. Also, we will make sure that the action corresponds to the character's animation.
For this recipe, we have prepared a project named MixamoProject
, containing several assets such as levels, animated characters, and props. You can find it inside the 0423_05_codes
folder.
To make an animated character throw an Easter egg(!), follow these steps:
ThrowObject.cs
.using UnityEngine; using System.Collections; public class ThrowObject : MonoBehaviour { public GameObject projectile; public Vector3 projectileOffset; public Vector3 projectileForce; public Transform charactersHand; public float lenghtPrepare; public float lenghtThrow; public float compensationYAngle = 20.0f; private bool prepared = false; private bool threw = false; private Animator animator; public void Start(){ animator = GetComponent<Animator>(); } public void LateUpdate(){ AnimatorStateInfo stateInfo = animator.GetCurrentAnimatorStateInfo(1); if(stateInfo.IsName("UpperBody.Grenade")){ if(stateInfo.normalizedTime >= lenghtPrepare * 0.01 && !prepared) Prepare(); if(stateInfo.normalizedTime >= lenghtThrow * 0.01 && !threw) Throw(); } else { prepared = false; threw = false; } } public void Prepare () { prepared = true; projectile = Instantiate(projectile, charactersHand.position, charactersHand.rotation) as GameObject; if(projectile.GetComponent<Rigidbody>()) Destroy(projectile.rigidbody); projectile.GetComponent<SphereCollider>().enabled = false; projectile.name = "projectile"; projectile.transform.parent = charactersHand; projectile.transform.localPosition = projectileOffset; projectile.transform.localEulerAngles = Vector3.zero; } public void Throw () { threw = true; Vector3 dir = transform.rotation.eulerAngles; dir.y += compensationYAngle; projectile.transform.rotation = Quaternion.Euler(dir); projectile.transform.parent = null; projectile.GetComponent<SphereCollider>().enabled = true; projectile.AddComponent<Rigidbody>(); Physics.IgnoreCollision(projectile.collider, collider); projectile.rigidbody.AddRelativeForce(projectileForce); } }
-0.07
, Y: -0.04
, Z: 0
; Projectile Force: X: 0
, Y: 200
, Z: 500
.Likewise, it finishes the throw movement around 1:24 (57 percent of the length), as shown in the following screenshot:
12
and 57
respectively.-45
.Once the toss_grenade animation reaches 12 percent of its length, our script detects it and calls the function named Prepare()
.This function instantiates a Prefab, now named projectile, into the character's hand. The values specified under Projectile Offset are used to fine-tune its position, making it respect the character's hierarchy. Also, it disables the Prefab's collider and destroys its Rigidbody component, provided it has one.
Later, when the toss_grenade animation reaches 57 percent of its length, the Throw()
function is called, which enables the projectile's collider, adds a Rigidbody component to it, and makes it independent of the Character object. Finally, it adds a relative force to the projectile's Rigidbody component so it behaves as if it was thrown by the character. Compensation YAngle is used to adjust the direction of the grenade.
18.218.187.108