使用


using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public enum eOrientationMode { NODE = 0, TANGENT }

[AddComponentMenu("Splines/Spline Controller")]
[RequireComponent(typeof(SplineInterpolator))]
public class SplineController : MonoBehaviour
{
	public static SplineController Thiss;
	public GameObject SplineRoot;
	public string childName = "pivot";
	public int startIndex = 1;
	public float Duration = 1;
	public float currentLength = 0;
	public eOrientationMode OrientationMode = eOrientationMode.NODE;
	public eWrapMode WrapMode = eWrapMode.ONCE;
	public bool AutoStart = true;
	public bool AutoClose = false;
	public bool HideOnExecute = true;
	public float dis;
	SplineInterpolator mSplineInterp;
	public Transform[] mTransforms;
	public bool useNewMeth = false;
	
	void Start () 
	{
		Thiss = this;
	}
	
	public void Setup()
	{
		mSplineInterp = GetComponent(typeof(SplineInterpolator)) as SplineInterpolator;
		SetupSplineInterpolator();
		mSplineInterp.StartInterpolation(true, WrapMode);/**????????**/
	}
	
	/// <summary>
	/// 
	/// </summary>
	[ContextMenu("GetAllChildAndInit")]
	public void GetAllChildAndInit()
	{
		
		mTransforms = new Transform[SplineRoot.transform.childCount];
		
		for(int i = 0; i < SplineRoot.transform.childCount; i ++)
		{
			mTransforms[i] = SplineRoot.transform.FindChild(childName + string.Format("{0:D2}", startIndex + i));
		}
		
		Setup();
		//		if(EnemySplineRoot == null) return;
		//		EnemymTransforms = new Transform[EnemySplineRoot.transform.childCount];
		//		for(int i = 0; i < EnemySplineRoot.transform.childCount; i++)
		//		{
		//			EnemymTransforms[i] = EnemySplineRoot.transform.FindChild("pivot"+string.Format("{0:D2}",EnemychildIndex+i));
		//		}
		//		EnemySetup();
	}
	
	/// <summary>
	/// 
	/// </summary>
		void OnDrawGizmos()
		{
		     
			if (mTransforms == null || mTransforms.Length < 2)
			{
//			if(mTransforms.Length < 2){
//			Debug.Log ("mTransforms.Length:"+mTransforms.Length);
//			}
		
				return;
			}
		   
			for(int i=0; i < mTransforms.Length; i++)
			{
				if(mTransforms[i] == null)
				{
					return;
				}
			}
			
			Vector3 prevPos = mTransforms[0].position;
			float currTime = 0;
			Gizmos.color = Color.red;
			if(mSplineInterp == null) return;
			while(currTime < Duration)
			{
				currTime += 0.01f;
				Vector3 currPos = mSplineInterp.GetHermiteAtTime(currTime);
				float mag = (currPos-prevPos).magnitude * 2;
				//Gizmos.color = new Color(mag, 0, 0, 1);
				Gizmos.DrawLine(prevPos, currPos);
				prevPos = currPos;
			}
		}
	
	
	//	public float perDis;
	/// <summary>
	//
	/// </summary>
	public void SetupSplineInterpolator()
	{
		mSplineInterp.Reset();
		
		float step = (AutoClose) ? Duration / mTransforms.Length :
			Duration / (mTransforms.Length - 1);
		
		
		
		Transform lastChilid = null;
		float totalDis = 0.0f;
		float[] stepList = new float[ mTransforms.Length];
		int i = 0;
		float perTime = (AutoClose) ? Duration / mTransforms.Length : Duration / (mTransforms.Length - 1);
		float perDis = 0.0f;
		
		foreach(Transform child in mTransforms)
		{
			if(lastChilid == null)
			{
				lastChilid = child;
				continue;
			}
			
			totalDis += Vector3.Distance(child.position , lastChilid.position);
			
			lastChilid = child;
		}
		perDis = (AutoClose) ? totalDis / mTransforms.Length : totalDis / (mTransforms.Length - 1);
		lastChilid = null;
		i = 0;
		
		foreach(Transform child in mTransforms)
		{
			if(lastChilid == null) 
			{
				lastChilid = child;
				stepList[i] = 0f;
				i ++;
				continue;
			}
			
			/**Vector3.Distance(child.position, lastChilid.position) 
			float t = Vector3.Distance(child.position, lastChilid.position) / perDis * perTime;
			stepList[i] = t + stepList[i - 1];
			//			Debug.Log (i + " Time:" + t + " ArriveTime:" + stepList[i] + " " + " perT:" + perTime + " dis:" + Vector3.Distance(child.position, lastChilid.position) + " perDis:" + perDis);
			i ++;
			lastChilid = child;
		}
		
		/**end*******************************************************************************************************************/
		
		
		int c;
		for (c = 0; c < mTransforms.Length; c++)
		{
			if (OrientationMode == eOrientationMode.NODE)
			{
				if(!useNewMeth) mSplineInterp.AddPoint(mTransforms[c].position, mTransforms[c].rotation, step * c, new Vector2(0, 1));
				else mSplineInterp.AddPoint(mTransforms[c].position, mTransforms[c].rotation, stepList[c], new Vector2(0, 1));
				
				//				Debug.Log ("C:" + c + ", stepList[c]:" + stepList[c]);
			}
			else if (OrientationMode == eOrientationMode.TANGENT)
			{
				Quaternion rot;
				if (c != mTransforms.Length - 1)
					rot = Quaternion.LookRotation(mTransforms[c + 1].position - mTransforms[c].position, mTransforms[c].up);
				else if (AutoClose)
					rot = Quaternion.LookRotation(mTransforms[0].position - mTransforms[c].position, mTransforms[c].up);
				else
					rot = mTransforms[c].rotation;
				if(!useNewMeth) mSplineInterp.AddPoint(mTransforms[c].position, rot, step * c, new Vector2(0, 1));
				else mSplineInterp.AddPoint(mTransforms[c].position, rot, stepList[c], new Vector2(0, 1));
			}
		}
		
		if (AutoClose)
			if(!useNewMeth) mSplineInterp.SetAutoCloseMode(step * c);
		else mSplineInterp.SetAutoCloseMode(stepList[c]);
	}
	
	
	public Vector3 getPoint(float percent)
	{
		return mSplineInterp.GetHermiteAtTime(percent * Duration);
	}
	

	public PositionAndRotationValue getPointAtTime(float time)
	{
		return mSplineInterp.getPointAndRotationAtTime(time);
		//return mSplineInterp.GetHermiteAtTime(time);
	}
	
	public Quaternion getQuaternion(float percent)
	{
		return mSplineInterp.GetQuaternionAtTime(percent * Duration);
	}
	
	public Quaternion GetQuaternionAtTime(float time)
	{
		return mSplineInterp.GetQuaternionAtTime(time);
	}
	
	[ContextMenu("rename children")]
	void RenameChildren()
	{
		for(int i = 0; i < mTransforms.Length; i++)
		{
			mTransforms[i].name = "pivot" + string.Format("{0:D2}", i+1);
		}
	}


/********************************m_14_7_2**********************************************************************************/

	public void setSplineRoot(GameObject sproot){
		SplineRoot = sproot;
	}








}







public class GameObjectNameComparer : IComparer
{
	int IComparer.Compare(object a, object b)
	{
		return ((Transform)a).name.CompareTo(((Transform)b).name);
	}
}


using UnityEngine;
using System.Collections;

public class MathUtils
{
	public static float GetQuatLength(Quaternion q)
	{
		return Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
	}

	public static Quaternion GetQuatConjugate(Quaternion q)
	{
		return new Quaternion(-q.x, -q.y, -q.z, q.w);
	}

	/// <summary>
	/// Logarithm of a unit quaternion. The result is not necessary a unit quaternion.
	/// </summary>
	public static Quaternion GetQuatLog(Quaternion q)
	{
		Quaternion res = q;
		res.w = 0;

		if (Mathf.Abs(q.w) < 1.0f)
		{
			float theta = Mathf.Acos(q.w);
			float sin_theta = Mathf.Sin(theta);

			if (Mathf.Abs(sin_theta) > 0.0001)
			{
				float coef = theta / sin_theta;
				res.x = q.x * coef;
				res.y = q.y * coef;
				res.z = q.z * coef;
			}
		}

		return res;
	}

	public static Quaternion GetQuatExp(Quaternion q)
	{
		Quaternion res = q;

		float fAngle = Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z);
		float fSin = Mathf.Sin(fAngle);

		res.w = Mathf.Cos(fAngle);

		if (Mathf.Abs(fSin) > 0.0001)
		{
			float coef = fSin / fAngle;
			res.x = coef * q.x;
			res.y = coef * q.y;
			res.z = coef * q.z;
		}

		return res;
	}

	/// <summary>
	/// SQUAD Spherical Quadrangle interpolation [Shoe87]
	/// </summary>
	public static Quaternion GetQuatSquad(float t, Quaternion q0, Quaternion q1, Quaternion a0, Quaternion a1)
	{
		float slerpT = 2.0f * t * (1.0f - t);

		Quaternion slerpP = Slerp(q0, q1, t);
		Quaternion slerpQ = Slerp(a0, a1, t);

		return Slerp(slerpP, slerpQ, slerpT);
	}

	public static Quaternion GetSquadIntermediate(Quaternion q0, Quaternion q1, Quaternion q2)
	{
		Quaternion q1Inv = GetQuatConjugate(q1);
		Quaternion p0 = GetQuatLog(q1Inv * q0);
		Quaternion p2 = GetQuatLog(q1Inv * q2);
		Quaternion sum = new Quaternion(-0.25f * (p0.x + p2.x), -0.25f * (p0.y + p2.y), -0.25f * (p0.z + p2.z), -0.25f * (p0.w + p2.w));

		return q1 * GetQuatExp(sum);
	}

	/// <summary>
	/// Smooths the input parameter t.
	/// If less than k1 ir greater than k2, it uses a sin.
	/// Between k1 and k2 it uses linear interp.
	/// </summary>
	public static float Ease(float t, float k1, float k2)
	{
		float f; float s;

		f = k1 * 2 / Mathf.PI + k2 - k1 + (1.0f - k2) * 2 / Mathf.PI;

		if (t < k1)
		{
			s = k1 * (2 / Mathf.PI) * (Mathf.Sin((t / k1) * Mathf.PI / 2 - Mathf.PI / 2) + 1);
		}
		else
			if (t < k2)
			{
				s = (2 * k1 / Mathf.PI + t - k1);
			}
			else
			{
				s = 2 * k1 / Mathf.PI + k2 - k1 + ((1 - k2) * (2 / Mathf.PI)) * Mathf.Sin(((t - k2) / (1.0f - k2)) * Mathf.PI / 2);
			}

		return (s / f);
	}

	/// <summary>
	/// We need this because Quaternion.Slerp always uses the shortest arc.
	/// </summary>
	public static Quaternion Slerp(Quaternion p, Quaternion q, float t)
	{
		Quaternion ret;

		float fCos = Quaternion.Dot(p, q);

		if ((1.0f + fCos) > 0.00001)
		{
			float fCoeff0, fCoeff1;

			if ((1.0f - fCos) > 0.00001)
			{
				float omega = Mathf.Acos(fCos);
				float invSin = 1.0f / Mathf.Sin(omega);
				fCoeff0 = Mathf.Sin((1.0f - t) * omega) * invSin;
				fCoeff1 = Mathf.Sin(t * omega) * invSin;
			}
			else
			{
				fCoeff0 = 1.0f - t;
				fCoeff1 = t;
			}

			ret.x = fCoeff0 * p.x + fCoeff1 * q.x;
			ret.y = fCoeff0 * p.y + fCoeff1 * q.y;
			ret.z = fCoeff0 * p.z + fCoeff1 * q.z;
			ret.w = fCoeff0 * p.w + fCoeff1 * q.w;
		}
		else
		{
			float fCoeff0 = Mathf.Sin((1.0f - t) * Mathf.PI * 0.5f);
			float fCoeff1 = Mathf.Sin(t * Mathf.PI * 0.5f);

			ret.x = fCoeff0 * p.x - fCoeff1 * p.y;
			ret.y = fCoeff0 * p.y + fCoeff1 * p.x;
			ret.z = fCoeff0 * p.z - fCoeff1 * p.w;
			ret.w = p.z;
		}

		return ret;
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值