View difference between Paste ID: A3Ju7kZr and G6HRBs3C
SHOW: | | - or go back to the newest paste.
1
using System.Collections;
2
using System.Collections.Generic;
3
using UnityEngine;
4
 
5
public class CharacterIK : MonoBehaviour {
6
 
7
    Animator anim;
8
 
9
    Transform leftFoot;
10
    Transform rightFoot;
11
 
12
    Transform rightShoulder;
13
    Transform leftShoulder;
14
 
15
    Vector3 leftFoot_pos;
16
    Vector3 rightFoot_pos;
17
   
18
    Quaternion leftFoot_rot;
19
    Quaternion rightFoot_rot;
20
 
21
    Vector3 leftHand_pos;
22
    Vector3 rightHand_pos;
23
 
24
    Quaternion leftHand_rot;
25
    Quaternion rightHand_rot;
26
 
27
    float leftFoot_Weight;
28
    float rightFoot_Weight;
29
 
30
    float leftHand_Weight;
31
    float rightHand_Weight;
32
 
33
    public Transform lookAtThis;
34
 
35
    private void Start()
36
    {
37
        anim = GetComponent<Animator>();
38
        leftFoot = anim.GetBoneTransform(HumanBodyBones.LeftFoot);
39
        rightFoot = anim.GetBoneTransform(HumanBodyBones.RightFoot);
40
        leftShoulder = anim.GetBoneTransform(HumanBodyBones.LeftShoulder);
41
        rightShoulder = anim.GetBoneTransform(HumanBodyBones.RightShoulder);
42
    }
43
    private void OnAnimatorIK(int layerIndex)
44
    {
45
        // foot IK
46
        leftFoot_Weight = anim.GetFloat("LeftFoot");
47
        rightFoot_Weight = anim.GetFloat("RightFoot");
48
        // find raycast positions
49
        FindFloorPositions(leftFoot, ref leftFoot_pos, ref leftFoot_rot, Vector3.up);
50
        FindFloorPositions(rightFoot, ref rightFoot_pos, ref rightFoot_rot, Vector3.up);
51
 
52
        // replace the weights with leftFoot_Weight, and rightFoot_Weight when you've set them in your animation's Curves
53
        anim.SetIKPositionWeight(AvatarIKGoal.LeftFoot, 1);
54
        anim.SetIKRotationWeight(AvatarIKGoal.LeftFoot, 1);
55
 
56
        anim.SetIKPositionWeight(AvatarIKGoal.RightFoot, 1);
57
        anim.SetIKRotationWeight(AvatarIKGoal.RightFoot, 1);
58
 
59
        // set the position of the feet
60
        anim.SetIKPosition(AvatarIKGoal.LeftFoot, leftFoot_pos);
61
        anim.SetIKPosition(AvatarIKGoal.RightFoot, rightFoot_pos);
62
 
63
        // set the rotation of the feet
64
        anim.SetIKRotation(AvatarIKGoal.LeftFoot, leftFoot_rot);
65
        anim.SetIKRotation(AvatarIKGoal.RightFoot, rightFoot_rot);
66
 
67
        // hand IK
68
 
69
        // find raycast positions
70
        FindFloorPositions(leftShoulder, ref leftHand_pos, ref leftHand_rot, -transform.forward);
71
        FindFloorPositions(rightShoulder, ref rightHand_pos, ref rightHand_rot, -transform.forward);
72
 
73
        // distance between hands and raycast hit
74
        float distanceRightArmObject = Vector3.Distance(anim.GetBoneTransform(HumanBodyBones.RightShoulder).position, rightHand_pos);
75
        float distanceLeftArmObject = Vector3.Distance(anim.GetBoneTransform(HumanBodyBones.LeftShoulder).position, leftHand_pos);
76
        // blend weight based on the distance
77
        leftHand_Weight = Mathf.Clamp01(1 - distanceLeftArmObject);
78
        rightHand_Weight = Mathf.Clamp01(1 - distanceRightArmObject);
79
 
80
       
81
        anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, leftHand_Weight);
82
        anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, leftHand_Weight);
83
 
84
        anim.SetIKPositionWeight(AvatarIKGoal.RightHand, rightHand_Weight);
85
        anim.SetIKRotationWeight(AvatarIKGoal.RightHand, rightHand_Weight);
86
 
87
        // set the position of the hand
88
        anim.SetIKPosition(AvatarIKGoal.LeftHand, leftHand_pos);
89
        anim.SetIKPosition(AvatarIKGoal.RightHand, rightHand_pos);
90
 
91
        // set the rotation of the hand
92
        anim.SetIKRotation(AvatarIKGoal.LeftHand, leftHand_rot);
93
        anim.SetIKRotation(AvatarIKGoal.RightHand, rightHand_rot);
94
        // head IK
95
        if (lookAtThis != null)
96
        {
97
            // distance between face and object to look at
98
            float distanceFaceObject = Vector3.Distance(anim.GetBoneTransform(HumanBodyBones.Head).position, lookAtThis.position);
99
           
100
            anim.SetLookAtPosition(lookAtThis.position);
101
            // blend based on the distance
102
            anim.SetLookAtWeight(Mathf.Clamp01(2 - distanceFaceObject), Mathf.Clamp01(1 - distanceFaceObject));
103
        }
104
    }
105
 
106
    void FindFloorPositions(Transform t, ref Vector3 targetPosition, ref Quaternion targetRotation, Vector3 direction)
107
    {
108
        RaycastHit hit;
109
        Vector3 rayOrigin = t.position;
110
        // move the ray origin back a bit
111
        rayOrigin += direction * 0.3f;
112
 
113
        // raycast in the given direction
114
        Debug.DrawRay(rayOrigin, -direction, Color.green);
115
        if (Physics.Raycast(rayOrigin, -direction, out hit, 3))
116
        {
117
            // the hit point is the position of the hand/foot
118
            targetPosition = hit.point;            
119
            // then rotate based on the hit normal
120
            Quaternion rot = Quaternion.LookRotation(transform.forward);          
121
            targetRotation = Quaternion.FromToRotation(Vector3.up, hit.normal) * rot;          
122
        }
123
    }
124
}