136 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //
 | ||
| //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);
 | ||
| 			}
 | ||
| 		}
 | ||
| 	}
 | ||
| }
 |