首页 > 代码库 > MMD 学习

MMD 学习

技术分享

技术分享
  1 using UnityEngine;
  2 using System.Collections;
  3 
  4 namespace UnityChan
  5 {
  6     public class SpringBone : MonoBehaviour
  7     {
  8         
  9         public Transform child;
 10 
 11         
 12         public Vector3 boneAxis = new Vector3 (-1.0f, 0.0f, 0.0f);
 13         public float radius = 0.05f;
 14 
 15         
 16         public bool isUseEachBoneForceSettings = false; 
 17 
 18         
 19         public float stiffnessForce = 0.01f;
 20 
 21     
 22         public float dragForce = 0.4f;
 23         public Vector3 springForce = new Vector3 (0.0f, -0.0001f, 0.0f);
 24         public SpringCollider[] colliders;
 25         public bool debug = true;
 26         
 27         public float threshold = 0.01f;
 28         private float springLength;
 29         private Quaternion localRotation;
 30         private Transform trs;
 31         private Vector3 currTipPos;
 32         private Vector3 prevTipPos;
 33         
 34         private Transform org;
 35         
 36         private SpringManager managerRef;
 37 
 38         private void Awake ()
 39         {
 40             trs = transform;
 41             localRotation = transform.localRotation;
 42             
 43             managerRef = GetParentSpringManager (transform);
 44         }
 45 
 46         private SpringManager GetParentSpringManager (Transform t)
 47         {
 48             var springManager = t.GetComponent<SpringManager> ();
 49 
 50             if (springManager != null)
 51                 return springManager;
 52 
 53             if (t.parent != null) {
 54                 return GetParentSpringManager (t.parent);
 55             }
 56 
 57             return null;
 58         }
 59 
 60         private void Start ()
 61         {
 62             springLength = Vector3.Distance (trs.position, child.position);
 63             currTipPos = child.position;
 64             prevTipPos = child.position;
 65         }
 66 
 67         public void UpdateSpring ()
 68         {
 69             
 70             org = trs;
 71             
 72             trs.localRotation = Quaternion.identity * localRotation;
 73 
 74             float sqrDt = Time.deltaTime * Time.deltaTime;
 75 
 76             //stiffness
 77             Vector3 force = trs.rotation * (boneAxis * stiffnessForce) / sqrDt;
 78 
 79             //drag
 80             force += (prevTipPos - currTipPos) * dragForce / sqrDt;
 81 
 82             force += springForce / sqrDt;
 83 
 84             
 85             Vector3 temp = currTipPos;
 86 
 87             //verlet
 88             currTipPos = (currTipPos - prevTipPos) + currTipPos + (force * sqrDt);
 89 
 90             
 91             currTipPos = ((currTipPos - trs.position).normalized * springLength) + trs.position;
 92 
 93             
 94             for (int i = 0; i < colliders.Length; i++) {
 95                 if (Vector3.Distance (currTipPos, colliders [i].transform.position) <= (radius + colliders [i].radius)) {
 96                     Vector3 normal = (currTipPos - colliders [i].transform.position).normalized;
 97                     currTipPos = colliders [i].transform.position + (normal * (radius + colliders [i].radius));
 98                     currTipPos = ((currTipPos - trs.position).normalized * springLength) + trs.position;
 99                 }
100 
101 
102             }
103 
104             prevTipPos = temp;
105 
106             
107             Vector3 aimVector = trs.TransformDirection (boneAxis);
108             Quaternion aimRotation = Quaternion.FromToRotation (aimVector, currTipPos - trs.position);
109             
110             Quaternion secondaryRotation = aimRotation * trs.rotation;
111             trs.rotation = Quaternion.Lerp (org.rotation, secondaryRotation, managerRef.dynamicRatio);
112         }
113 
114         private void OnDrawGizmos ()
115         {
116             if (debug) {
117                 Gizmos.color = Color.yellow;
118                 Gizmos.DrawWireSphere (currTipPos, radius);
119             }
120         }
121     }
122 }
SpringBone
技术分享
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 namespace UnityChan
 5 {
 6     public class SpringCollider : MonoBehaviour
 7     {
 8         //半径
 9         public float radius = 0.5f;
10 
11         private void OnDrawGizmosSelected ()
12         {
13             Gizmos.color = Color.green;
14             Gizmos.DrawWireSphere (transform.position, radius);
15         }
16     }
17 }
SpringCollider
技术分享
 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 namespace UnityChan
 5 {
 6     public class SpringManager : MonoBehaviour
 7     {
 8         //Kobayashi
 9         // DynamicRatio is paramater for activated level of dynamic animation 
10         public float dynamicRatio = 1.0f;
11 
12         //Ebata
13         public float            stiffnessForce;
14         public AnimationCurve    stiffnessCurve;
15         public float            dragForce;
16         public AnimationCurve    dragCurve;
17         public SpringBone[] springBones;
18 
19         void Start ()
20         {
21             UpdateParameters ();
22         }
23     
24         void Update ()
25         {
26 #if UNITY_EDITOR
27         
28         if(dynamicRatio >= 1.0f)
29             dynamicRatio = 1.0f;
30         else if(dynamicRatio <= 0.0f)
31             dynamicRatio = 0.0f;
32         //Ebata
33         UpdateParameters();
34 #endif
35         }
36     
37         private void LateUpdate ()
38         {
39             
40             if (dynamicRatio != 0.0f) {
41                 for (int i = 0; i < springBones.Length; i++) {
42                     if (dynamicRatio > springBones [i].threshold) {
43                         springBones [i].UpdateSpring ();
44                     }
45                 }
46             }
47         }
48 
49         private void UpdateParameters ()
50         {
51             UpdateParameter ("stiffnessForce", stiffnessForce, stiffnessCurve);
52             UpdateParameter ("dragForce", dragForce, dragCurve);
53         }
54     
55         private void UpdateParameter (string fieldName, float baseValue, AnimationCurve curve)
56         {
57             var start = curve.keys [0].time;
58             var end = curve.keys [curve.length - 1].time;
59             //var step    = (end - start) / (springBones.Length - 1);
60         
61             var prop = springBones [0].GetType ().GetField (fieldName, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
62         
63             for (int i = 0; i < springBones.Length; i++) {
64                 
65                 if (!springBones [i].isUseEachBoneForceSettings) {
66                     var scale = curve.Evaluate (start + (end - start) * i / (springBones.Length - 1));
67                     prop.SetValue (springBones [i], baseValue * scale);
68                 }
69             }
70         }
71     }
72 }
SpringManager

视频:https://pan.baidu.com/s/1nvmEC3Z

项目:https://pan.baidu.com/s/1qYbdgqK

用到的资源:https://pan.baidu.com/s/1miLm6O4

MMD 学习