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);
|
||
}
|
||
}
|
||
}
|
||
}
|