1 //
2
3 //SpringBone.cs for unity-chan!
4
5 //
6
7 //Original Script is here:
8
9 //ricopin / SpringBone.cs
10
11 //Rocket Jump : http://rocketjump.skr.jp/unity3d/109/
12
13 //https://twitter.com/ricopin416
14
15 //
16
17 //Revised by N.Kobayashi 2014/06/20
18
19 //
20
21 using UnityEngine;
22
23 using System.Collections;
24
25
26
27 namespace UnityChan
28
29 {
30
31 public class SpringBone : MonoBehaviour
32
33 {
34
35 //次のボーン
36
37 public Transform child;
38
39
40
41 //ボーンの向き
42
43 public Vector3 boneAxis = new Vector3 (-1.0f, 0.0f, 0.0f);
44
45 public float radius = 0.05f;
46
47
48
49 //各SpringBoneに設定されているstiffnessForceとdragForceを使用するか?
50
51 public bool isUseEachBoneForceSettings = false;
52
53
54
55 //バネが戻る力
56
57 public float stiffnessForce = 0.01f;
58
59
60
61 //力の減衰力
62
63 public float dragForce = 0.4f;
64
65 public Vector3 springForce = new Vector3 (0.0f, -0.0001f, 0.0f);
66
67 public SpringCollider[] colliders;
68
69 public bool debug = true;
70
71 //Kobayashi:Thredshold Starting to activate activeRatio
72
73 public float threshold = 0.01f;
74
75 private float springLength;
76
77 private Quaternion localRotation;
78
79 private Transform trs;
80
81 private Vector3 currTipPos;
82
83 private Vector3 prevTipPos;
84
85 //Kobayashi
86
87 private Transform org;
88
89 //Kobayashi:Reference for "SpringManager" component with unitychan
90
91 private SpringManager managerRef;
92
93
94
95 private void Awake ()
96
97 {
98
99 trs = transform;
100
101 localRotation = transform.localRotation;
102
103 //Kobayashi:Reference for "SpringManager" component with unitychan
104
105 // GameObject.Find("unitychan_dynamic").GetComponent<SpringManager>();
106
107 managerRef = GetParentSpringManager (transform);
108
109 }
110
111
112
113 private SpringManager GetParentSpringManager (Transform t)
114
115 {
116
117 var springManager = t.GetComponent<SpringManager> ();
118
119
120
121 if (springManager != null)
122
123 return springManager;
124
125
126
127 if (t.parent != null) {
128
129 return GetParentSpringManager (t.parent);
130
131 }
132
133
134
135 return null;
136
137 }
138
139
140
141 private void Start ()
142
143 {
144
145 springLength = Vector3.Distance (trs.position, child.position);
146
147 currTipPos = child.position;
148
149 prevTipPos = child.position;
150
151 }
152
153
154
155 public void UpdateSpring ()
156
157 {
158
159 //Kobayashi
160
161 org = trs;
162
163 //回転をリセット
164
165 trs.localRotation = Quaternion.identity * localRotation;
166
167
168
169 float sqrDt = Time.deltaTime * Time.deltaTime;
170
171
172
173 //stiffness
174
175 Vector3 force = trs.rotation * (boneAxis * stiffnessForce) / sqrDt;
176
177
178
179 //drag
180
181 force += (prevTipPos - currTipPos) * dragForce / sqrDt;
182
183
184
185 force += springForce / sqrDt;
186
187
188
189 //前フレームと値が同じにならないように
190
191 Vector3 temp = currTipPos;
192
193
194
195 //verlet
196
197 currTipPos = (currTipPos - prevTipPos) + currTipPos + (force * sqrDt);
198
199
200
201 //長さを元に戻す
202
203 currTipPos = ((currTipPos - trs.position).normalized * springLength) + trs.position;
204
205
206
207 //衝突判定
208
209 for (int i = 0; i < colliders.Length; i++) {
210
211 if (Vector3.Distance (currTipPos, colliders [i].transform.position) <= (radius + colliders [i].radius)) {
212
213 Vector3 normal = (currTipPos - colliders [i].transform.position).normalized;
214
215 currTipPos = colliders [i].transform.position + (normal * (radius + colliders [i].radius));
216
217 currTipPos = ((currTipPos - trs.position).normalized * springLength) + trs.position;
218
219 }
220
221
222
223
224
225 }
226
227
228
229 prevTipPos = temp;
230
231
232
233 //回転を適用;
234
235 Vector3 aimVector = trs.TransformDirection (boneAxis);
236
237 Quaternion aimRotation = Quaternion.FromToRotation (aimVector, currTipPos - trs.position);
238
239 //original
240
241 //trs.rotation = aimRotation * trs.rotation;
242
243 //Kobayahsi:Lerp with mixWeight
244
245 Quaternion secondaryRotation = aimRotation * trs.rotation;
246
247 trs.rotation = Quaternion.Lerp (org.rotation, secondaryRotation, managerRef.dynamicRatio);
248
249 }
250
251
252
253 private void OnDrawGizmos ()
254
255 {
256
257 if (debug) {
258
259 Gizmos.color = Color.yellow;
260
261 Gizmos.DrawWireSphere (currTipPos, radius);
262
263 }
264
265 }
266
267 }
268
269 }