Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- namespace AGD.Core.IK
- {
- /// <summary>
- /// To be placed on a character in order to add a foot IK grounding behaviour
- /// Requires an Animator with a Layer set to IK Pass
- /// </summary>
- [RequireComponent(typeof(Animator))]
- public class FootIK : MonoBehaviour
- {
- private Animator _animator;
- [Tooltip("Set to false and this script won't run.")]
- [SerializeField] private bool applyFootIK = true;
- [Tooltip("Select the layer to which the foot IK will be applied")]
- [SerializeField] private LayerMask targetLayer;
- [Tooltip("the distance from the IK Foot Transform to the lowest point of the foot")]
- [Range(0,1)][SerializeField] private float distanceToGround = 0;
- private void Start()
- {
- _animator = GetComponent<Animator>();
- }
- private void OnAnimatorIK(int layerIndex)
- {
- if (!applyFootIK) return;
- if (!_animator) return;
- // Set the weights of left foot to the current value defined by the curve in the animations.
- _animator.SetIKPositionWeight(AvatarIKGoal.LeftFoot, _animator.GetFloat("IKLeftFootWeight"));
- _animator.SetIKRotationWeight(AvatarIKGoal.LeftFoot, _animator.GetFloat("IKLeftFootWeight"));
- //Left Foot
- RaycastHit hitInfo;
- //a ray starting from 1 unit above the IK Foot transform, and going downward on the Y Axis
- Ray ray = new Ray(_animator.GetIKPosition(AvatarIKGoal.LeftFoot) + Vector3.up, Vector3.down);
- Debug.DrawRay(_animator.GetIKPosition(AvatarIKGoal.LeftFoot) + Vector3.up, Vector3.down * (1f + distanceToGround), Color.red);
- if (Physics.Raycast(ray, out hitInfo, 1f + distanceToGround, targetLayer))
- {
- var footPosition = hitInfo.point; //The point in space where the ray hit the targetLayer ie: where the foot should be placed.
- footPosition.y += distanceToGround; //lifting the foot back up to compensate for the distanceToGround used above.
- _animator.SetIKPosition(AvatarIKGoal.LeftFoot, footPosition);
- //Rotating the foot in a direction so that Vector3.up's rotation matches the hit surface's normal rotation.
- _animator.SetIKRotation(AvatarIKGoal.LeftFoot, Quaternion.FromToRotation(Vector3.up, hitInfo.normal));
- }
- // Set the weights of left foot to the current value defined by the curve in the animations.
- _animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, _animator.GetFloat("IKRightFootWeight"));
- _animator.SetIKRotationWeight(AvatarIKGoal.RightFoot, _animator.GetFloat("IKRightFootWeight"));
- //Right Foot
- //a ray starting from 1 unit above the IK Foot transform, and going downward on the Y Axis
- ray = new Ray(_animator.GetIKPosition(AvatarIKGoal.RightFoot) + Vector3.up, Vector3.down);
- Debug.DrawRay(_animator.GetIKPosition(AvatarIKGoal.LeftFoot) + Vector3.up, Vector3.down * (1f + distanceToGround), Color.red);
- if (Physics.Raycast(ray, out hitInfo, 1f + distanceToGround, targetLayer))
- {
- var footPosition = hitInfo.point; //The point in space where the ray hit the targetLayer ie: where the foot should be placed.
- footPosition.y += distanceToGround; //lifting the foot back up to compensate for the distanceToGround used above.
- _animator.SetIKPosition(AvatarIKGoal.RightFoot, footPosition);
- //Rotating the foot in a direction so that Vector3.up's rotation matches the hit surface's normal rotation.
- _animator.SetIKRotation(AvatarIKGoal.RightFoot, Quaternion.FromToRotation(Vector3.up, hitInfo.normal));
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement