1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- using RootMotion.Demos;
- using UnityEngine;
- using System.Collections;
- using RootMotion.FinalIK;
- namespace RootMotion.Demos {
- // Demonstrating 360-degree aiming system built with 6 static aiming poses and AimIK.
- public class SimpleAimingSystem : MonoBehaviour {
-
- [Tooltip("AimPoser is a tool that returns an animation name based on direction.")]
- public AimPoser aimPoser;
-
- [Tooltip("Reference to the AimIK component.")]
- public AimIK aim;
-
- [Tooltip("Reference to the LookAt component (only used for the head in this instance).")]
- public LookAtIK lookAt;
-
- [Tooltip("Reference to the Animator component.")]
- public Animator animator;
-
- [Tooltip("Time of cross-fading from pose to pose.")]
- public float crossfadeTime = 0.2f;
- [Tooltip("Will keep the aim target at a distance.")]
- public float minAimDistance = 0.5f;
-
- private AimPoser.Pose aimPose, lastPose;
- void Start() {
- // Disable IK components to manage their updating order
- aim.enabled = false;
- lookAt.enabled = false;
- }
-
- // LateUpdate is called once per frame
- void LateUpdate () {
- if (aim.solver.target == null) {
- Debug.LogWarning("AimIK and LookAtIK need to have their 'Target' value assigned.", transform);
- }
- // Switch aim poses (Legacy animation)
- Pose();
- // Update IK solvers
- aim.solver.Update();
- if (lookAt != null) lookAt.solver.Update();
- }
-
- private void Pose() {
- // Make sure aiming target is not too close (might make the solver instable when the target is closer to the first bone than the last bone is).
- LimitAimTarget();
- // Get the aiming direction
- Vector3 direction = (aim.solver.target.position - aim.solver.bones[0].transform.position);
- // Getting the direction relative to the root transform
- Vector3 localDirection = transform.InverseTransformDirection(direction);
-
- // Get the Pose from AimPoser
- aimPose = aimPoser.GetPose(localDirection);
-
- // If the Pose has changed
- if (aimPose != lastPose) {
- // Increase the angle buffer of the pose so we won't switch back too soon if the direction changes a bit
- aimPoser.SetPoseActive(aimPose);
-
- // Store the pose so we know if it changes
- lastPose = aimPose;
- }
-
- // Direct blending
- foreach (AimPoser.Pose pose in aimPoser.poses) {
- if (pose == aimPose) {
- DirectCrossFade(pose.name, 1f);
- } else {
- DirectCrossFade(pose.name, 0f);
- }
- }
- }
-
- // Make sure aiming target is not too close (might make the solver instable when the target is closer to the first bone than the last bone is).
- void LimitAimTarget() {
- Vector3 aimFrom = aim.solver.bones[0].transform.position;
- Vector3 direction = (aim.solver.target.position - aimFrom);
- direction = direction.normalized * Mathf.Max(direction.magnitude, minAimDistance);
-
- aim.solver.target.position = aimFrom + direction;
- }
-
- // Uses Mecanim's Direct blend trees for cross-fading
- private void DirectCrossFade(string state, float target) {
- float f = Mathf.MoveTowards(animator.GetFloat(state), target, Time.deltaTime * (1f / crossfadeTime));
- animator.SetFloat(state, f);
- }
- }
- }
|