unity3D NGUI 基于UIDraggablePanel实现滑动窗体,带位置图标

大兔子大兔子 提交于 2019-12-06 18:32:52

  最近由于工作需要学习UNITY3D,对于做PHP的程序猿挑战性灰常大,unity3D国内相关资料少得可怜唉!

根据需求做个防“天天爱消除”主界面左右滑动窗体的效果,百度搜到雨凇大神的一个帖子

NGUI研究院之自制 Scroll View实现触摸滚动相册效果(四)

不过效果不怎么理想,没有平滑的spring动画。研究NGUI自带的Example 7 - Scroll View (Panel) 例子

实现了如下效果:


UIDragSlider.cs: 该脚本扩展了UICenterOnChild.CS的功能!用于灰白点队列的初始化工作以及根据最近中心点的窗体下标控制白点显示的位置。

UIDragSlider.cs


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上面

如有疑问请站内

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!