unity3D NGUI 基於UIDraggablePanel實現滑動窗體,帶位置圖標

  最近因爲工做須要學習UNITY3D,對於作PHP的程序猿挑戰性灰常大,unity3D國內相關資料少得可憐唉! spring

根據需求作個防「每天愛消除」主界面左右滑動窗體的效果,百度搜到雨凇大神的一個帖子 c#

NGUI研究院之自制 Scroll View實現觸摸滾動相冊效果(四) ide

不過效果不怎麼理想,沒有平滑的spring動畫。研究NGUI自帶的Example 7 - Scroll View (Panel) 例子 學習

實現了以下效果: 動畫


UIDragSlider.cs: 該腳本擴展了UICenterOnChild.CS的功能!用於灰白點隊列的初始化工做以及根據最近中心點的窗體下標控制白點顯示的位置。

UIDragSlider.cs
ui


using UnityEngine;

/// <summary>
/// Ever wanted to be able to auto-center on an object within a draggable panel?
/// Attach this script to the container that has the objects to center on as its children.
/// </summary>

//[AddComponentMenu("NGUI/Interaction/Center On Child")]
public class UIDragSlider : MonoBehaviour
{
	/// <summary>
	/// The strength of the spring.
	/// </summary>

	public float springStrength = 8f;

	/// <summary>
	/// Callback to be triggered when the centering operation completes.
	/// </summary>

	public SpringPanel.OnFinished onFinished;
	
	//用來放置灰色、白色小點
	public Transform  ponit;
	//白色的小點
	public GameObject prefabMaskDot;
	//灰色的小點
	public GameObject prefabBaseDot;
	//白色小點的臨時對象
	private GameObject maskDot;
	//灰色、白色小點下方的起始位置。
	int start;
	UIDraggablePanel mDrag;
	GameObject mCenteredObject;

	/// <summary>
	/// Game object that the draggable panel is currently centered on.
	/// </summary>

	public GameObject centeredObject { get { return mCenteredObject; } }

	void OnEnable ()
	{
		Recenter ();
		//initSlider ();
	}

	void Start ()
	{
		initSlider ();
	}

	void OnDragFinished ()
	{
		if (enabled)
			Recenter ();
	}

	/// <summary>
	/// Recenter the draggable list on the center-most child.
	/// </summary>

	public void Recenter ()
	{
	
		if (mDrag == null) {
			mDrag = NGUITools.FindInParents<UIDraggablePanel> (gameObject);

			
			//mDrag = GameObject.Find("UIPanel (Clipped View)").GetComponent<UIDraggablePanel>();
			if (mDrag == null) {
				Debug.LogWarning (GetType () + " requires " + typeof(UIDraggablePanel) + " on a parent object in order to work", this);
				enabled = false;
				return;
			} else {
				//mDrag = mDrag.GetComponent<UIDraggablePanel>();
				mDrag.onDragFinished = OnDragFinished;
				//Debug.Log(mDrag.panel);
				if (mDrag.horizontalScrollBar != null)
					mDrag.horizontalScrollBar.onDragFinished = OnDragFinished;

				if (mDrag.verticalScrollBar != null)
					mDrag.verticalScrollBar.onDragFinished = OnDragFinished;
			}
		}
		
		if (mDrag.panel == null)
			return;
		
		// Calculate the panel's center in world coordinates
		Vector4 clip = mDrag.panel.clipRange;
		Transform dt = mDrag.panel.cachedTransform;
		Vector3 center = dt.localPosition;
		center.x += clip.x;
		center.y += clip.y;
		center = dt.parent.TransformPoint (center);

		// Offset this value by the momentum
		Vector3 offsetCenter = center - mDrag.currentMomentum * (mDrag.momentumAmount * 0.1f);
		mDrag.currentMomentum = Vector3.zero;

		float min = float.MaxValue;
		Transform closest = null;
		Transform trans = transform;

		// Determine the closest child
		for (int i = 0, imax = trans.childCount; i < imax; ++i) {
			Transform t = trans.GetChild (i);
			float sqrDist = Vector3.SqrMagnitude (t.position - offsetCenter);

			if (sqrDist < min) {
				min = sqrDist;
				closest = t;
			}
		}

		if (closest != null) {
			Debug.Log (closest.gameObject.name);
			mCenteredObject = closest.gameObject;
			
			// Figure out the difference between the chosen child and the panel's center in local coordinates
			Vector3 cp = dt.InverseTransformPoint (closest.position);
			Vector3 cc = dt.InverseTransformPoint (center);
			Vector3 offset = cp - cc;

			// Offset shouldn't occur if blocked by a zeroed-out scale
			if (mDrag.scale.x == 0f)
				offset.x = 0f;
			if (mDrag.scale.y == 0f)
				offset.y = 0f;
			if (mDrag.scale.z == 0f)
				offset.z = 0f;

			// Spring the panel to this calculated position
			SpringPanel.Begin (mDrag.gameObject, dt.localPosition - offset, springStrength).onFinished = onFinished;
			//兩個方法一個設置名字
			//獲取當前下標
			/*
			int index=0;
			foreach(Transform child in transform){
				if(child.gameObject==closest.gameObject){
					Debug.Log("index:"+index);
					setMaskPos(index);
				}
				index++;
			}
			*/
			//第二個方法須要命名
			string[] indexName = closest.gameObject.name.Split ('_');
			setMaskPos (int.Parse (indexName [1]));
			
			
		} else
			mCenteredObject = null;
	}

	void initSlider ()
	{
		//由於下方灰色 白色的小點須要根據相冊列表的數量來計算居中顯示
		int size = transform.childCount;
		//乘以16表示計算全部小點加起來的寬度
		int length = (size - 1) * 17;
		//獲得下方灰色 白色 小點的居中起始位置
		start = (-length) >> 1;
		for (int i=0; i< size; i++) {
			//把每個灰色小點加入3D世界
			GameObject hui = (GameObject)Instantiate (prefabBaseDot);
			//設置灰色小點的父類爲另一個面板
			hui.transform.parent = ponit;
			//設置每個灰色小點的位置與縮放,總之讓它們居中排列顯示在相冊列表下方。
			hui.transform.localPosition = new Vector3 (start + i * 24, -240f, 0f);
			hui.transform.localScale = new Vector3 (17, 17, 1);

			//深度 由於是先在屏幕下方繪製4個灰色的小點, 而後在灰色上面繪製白色小點
			//表示當前的窗口ID 因此深度是爲了設置白色小點在灰色小點之上繪製
			hui.GetComponent<UISprite> ().depth = 0;
		}
		//把白色小點也加載在3D世界中
		maskDot = (GameObject)Instantiate (prefabMaskDot);
		//設置它的深度高於 灰色小點,讓白色小點顯示在灰色小點之上
		maskDot.GetComponent<UISprite> ().depth = 1;
		//設置白色小點的開始位置
		setMaskPos (0);
		
	}

	void setMaskPos (int index)
	{
		maskDot.transform.parent = ponit;
		maskDot.transform.localPosition = new Vector3 (start + index * 24, -240f, -10f);
		maskDot.transform.localScale = new Vector3 (17, 17, 1);
		
	}
}
把腳本加到UIGrid上面

若有疑問請站內 this

相關文章
相關標籤/搜索