123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- //
- //SpringBone.cs for unity-chan!
- //
- //Original Script is here:
- //ricopin / SpringBone.cs
- //Rocket Jump : http://rocketjump.skr.jp/unity3d/109/
- //https://twitter.com/ricopin416
- //
- //Revised by N.Kobayashi 2014/06/20
- //
- using UnityEngine;
- using System.Collections;
- namespace UnityChan
- {
- public class SpringBone : MonoBehaviour
- {
- //次のボーン
- public Transform child;
- //ボーンの向き
- public Vector3 boneAxis = new Vector3 (-1.0f, 0.0f, 0.0f);
- public float radius = 0.05f;
- //各SpringBoneに設定されているstiffnessForceとdragForceを使用するか?
- public bool isUseEachBoneForceSettings = false;
- //バネが戻る力
- public float stiffnessForce = 0.01f;
- //力の減衰力
- public float dragForce = 0.4f;
- public Vector3 springForce = new Vector3 (0.0f, -0.0001f, 0.0f);
- public SpringCollider[] colliders;
- public bool debug = true;
- //Kobayashi:Thredshold Starting to activate activeRatio
- public float threshold = 0.01f;
- private float springLength;
- private Quaternion localRotation;
- private Transform trs;
- private Vector3 currTipPos;
- private Vector3 prevTipPos;
- //Kobayashi
- private Transform org;
- //Kobayashi:Reference for "SpringManager" component with unitychan
- private SpringManager managerRef;
- private void Awake ()
- {
- trs = transform;
- localRotation = transform.localRotation;
- //Kobayashi:Reference for "SpringManager" component with unitychan
- // GameObject.Find("unitychan_dynamic").GetComponent<SpringManager>();
- managerRef = GetParentSpringManager (transform);
- }
- private SpringManager GetParentSpringManager (Transform t)
- {
- var springManager = t.GetComponent<SpringManager> ();
- if (springManager != null)
- return springManager;
- if (t.parent != null) {
- return GetParentSpringManager (t.parent);
- }
- return null;
- }
- private void Start ()
- {
- springLength = Vector3.Distance (trs.position, child.position);
- currTipPos = child.position;
- prevTipPos = child.position;
- }
- public void UpdateSpring ()
- {
- //Kobayashi
- org = trs;
- //回転をリセット
- trs.localRotation = Quaternion.identity * localRotation;
- float sqrDt = Time.deltaTime * Time.deltaTime;
- //stiffness
- Vector3 force = trs.rotation * (boneAxis * stiffnessForce) / sqrDt;
- //drag
- force += (prevTipPos - currTipPos) * dragForce / sqrDt;
- force += springForce / sqrDt;
- //前フレームと値が同じにならないように
- Vector3 temp = currTipPos;
- //verlet
- currTipPos = (currTipPos - prevTipPos) + currTipPos + (force * sqrDt);
- //長さを元に戻す
- currTipPos = ((currTipPos - trs.position).normalized * springLength) + trs.position;
- //衝突判定
- for (int i = 0; i < colliders.Length; i++) {
- if (Vector3.Distance (currTipPos, colliders [i].transform.position) <= (radius + colliders [i].radius)) {
- Vector3 normal = (currTipPos - colliders [i].transform.position).normalized;
- currTipPos = colliders [i].transform.position + (normal * (radius + colliders [i].radius));
- currTipPos = ((currTipPos - trs.position).normalized * springLength) + trs.position;
- }
- }
- prevTipPos = temp;
- //回転を適用;
- Vector3 aimVector = trs.TransformDirection (boneAxis);
- Quaternion aimRotation = Quaternion.FromToRotation (aimVector, currTipPos - trs.position);
- //original
- //trs.rotation = aimRotation * trs.rotation;
- //Kobayahsi:Lerp with mixWeight
- Quaternion secondaryRotation = aimRotation * trs.rotation;
- trs.rotation = Quaternion.Lerp (org.rotation, secondaryRotation, managerRef.dynamicRatio);
- }
- private void OnDrawGizmos ()
- {
- if (debug) {
- Gizmos.color = Color.yellow;
- Gizmos.DrawWireSphere (currTipPos, radius);
- }
- }
- }
- }
|