http://blog.csdn.net/luyuncsd123/article/details/22914497
最近在做一个项目的UI,需求是1、拖动items后当永远有一个item保存在中间位置,2、点击当前item后当前item滑动到终点。 咱看了NGUI的Scroll View例子后发现第一个要求NGUI自带了,第二个要求没有,所以自己写了个包含这2个需求的脚本。 把相应的脚本替换成这几个就可以了。如果碰到变量保护之类的错误的话把父类中的方法改成protected就行了。 using UnityEngine; using System.Collections; [ExecuteInEditMode] public class QRCUICenterOnChild : UICenterOnChild { private Transform moveTarget; protected QRCUIDraggablePanel mQrcDrag; void OnEnable() { Recenter(null); //Recenter(); } void OnDragFinished(GameObject obj) { if (enabled) { //if (obj != null) Recenter(obj); //else // Recenter(); } } /// <summary> /// Recenter the draggable list on the center-most child. /// </summary> public void Recenter(GameObject obj) { if (mQrcDrag == null) { mQrcDrag = NGUITools.FindInParents<qrcuidraggablepanel>(gameObject); if (mQrcDrag == null) { Debug.LogWarning(GetType() + " requires " + typeof(QRCUIDraggablePanel) + " on a parent object in order to work", this); enabled = false; return; } else { mQrcDrag.onDragFinished = OnDragFinished; //if (mDrag.horizontalScrollBar != null) // mDrag.horizontalScrollBar.onDragFinished = OnDragFinished; //if (mDrag.verticalScrollBar != null) // mDrag.verticalScrollBar.onDragFinished = OnDragFinished; } } if (mQrcDrag.panel == null) return; // Calculate the panel's center in world coordinates Vector4 clip = mQrcDrag.panel.clipRange; Transform dt = mQrcDrag.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 - mQrcDrag.currentMomentum * (mQrcDrag.momentumAmount * 0.1f); mQrcDrag.currentMomentum = Vector3.zero; float min = float.MaxValue; Transform closest = null; Transform trans = transform; //Determine whether the user is to click on or drag if (obj != null) { closest = obj.transform; } else { closest = DetermineCloestChild(trans, offsetCenter, min, closest); } // Spring the panel to this calculated position MoveTargetPosition(closest, dt, center); } /// <summary> /// Determine the closest child /// </summary> public Transform DetermineCloestChild(Transform trans, Vector3 offsetCenter, float min, Transform closest) { 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; } } return closest; } /// <summary> /// Spring the panel to this calculated position /// </summary> public void MoveTargetPosition(Transform closest, Transform dt, Vector3 center) { if (closest != null) { 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 (mQrcDrag.scale.x == 0f) offset.x = 0f; if (mQrcDrag.scale.y == 0f) offset.y = 0f; if (mQrcDrag.scale.z == 0f) offset.z = 0f; // Spring the panel to this calculated position SpringPanel.Begin(mQrcDrag.gameObject, dt.localPosition - offset, 8f).onFinished = OnQrcFisished; } else mCenteredObject = null; } public delegate void OnQrcMoveToTragetFisished(GameObject obj); public event OnQrcMoveToTragetFisished OnQrcMoveToTragetFisishedHandler; /// <summary> /// After reaching the target this method will be used. /// </summary> public void OnQrcFisished() { OnQrcMoveToTragetFisishedHandler(mCenteredObject); } } ==================================================分割线================================================== using UnityEngine;using System.Collections; [ExecuteInEditMode] [RequireComponent(typeof(UIPanel))]public class QRCUIDraggablePanel : UIDraggablePanel { public delegate void OnDragFinished(GameObject obj); /// <summary> /// Event callback to trigger when the drag process finished. Can be used for additional effects, such as centering on some object. /// </summary> public OnDragFinished onDragFinished; public void Press(bool pressed, GameObject obj) { if (enabled && NGUITools.GetActive(gameObject)) { if (!pressed && mDragID == UICamera.currentTouchID) mDragID = -10; mCalculatedBounds = false; mShouldMove = shouldMove; if (!mShouldMove) return; mPressed = pressed; if (pressed) { // Remove all momentum on press mMomentum = Vector3.zero; mScroll = 0f; // Disable the spring movement DisableSpring(); // Remember the hit position mLastPos = UICamera.lastHit.point; // Create the plane to drag along mPlane = new Plane(mTrans.rotation * Vector3.back, mLastPos); } else { if (restrictWithinPanel && mPanel.clipping != UIDrawCall.Clipping.None && dragEffect == DragEffect.MomentumAndSpring) { RestrictWithinBounds(false); } if (onDragFinished != null) onDragFinished(obj); } } }} ===============================================分割线================================================ using UnityEngine;using System.Collections; [ExecuteInEditMode] public class QRCUIDragPanelContents : UIDragPanelContents{ private Vector3 previousTouch; /// <summary> /// Create a plane on which we will be performing the dragging. /// </summary> protected void OnPress(bool pressed) { bool isClick = false; Vector3 currentPos = Vector3.zero; //Judge runtime platform if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android) { if (Input.touchCount > 0) { currentPos = Input.GetTouch(0).position; } } else { currentPos = Input.mousePosition; } //Calculation is click ? if (pressed) { previousTouch = currentPos; } else { if (Vector3.Distance(previousTouch, currentPos) < 20.0f) { isClick = true; } } if (enabled && NGUITools.GetActive(gameObject) && draggablePanel != null) { QRCUIDraggablePanel qrcDraggablePanel = draggablePanel as QRCUIDraggablePanel; if (isClick) { qrcDraggablePanel.Press(false, gameObject); } else { qrcDraggablePanel.Press(pressed, null); } } isClick = false; } private bool IsClick() { if (Application.platform == RuntimePlatform.IPhonePlayer || Application.platform == RuntimePlatform.Android) { if (Input.touchCount > 0) { previousTouch = Input.GetTouch(0).position; } } return true; } //protected void OnClick() //{ // if (enabled && NGUITools.GetActive(gameObject) && draggablePanel != null) // { // QRCUIDraggablePanel qrcDraggablePanel = draggablePanel as QRCUIDraggablePanel; // qrcDraggablePanel.Press(false, gameObject); // } //} }