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 My")]
public class UICenterOnChild_My : MonoBehaviour
{
public SpringPanel.OnFinished onFinished;
public float strength = 8f;
public bool isCenterNext;
public AudioClip moveingSound;
public GameObject target;
public string functionName;
public bool includeChildren = false;
UIDraggablePanel mDrag;
GameObject mCenteredObject;
Vector3 mLastPos;
bool isMoved;
/// <summary>
/// Game object that the draggable panel is currently centered on.
/// </summary>
public GameObject centeredObject { get { return mCenteredObject; } }
void OnEnable () { Recenter(); }
void OnDragFinished () { if (enabled) Recenter(); if(isMoved)Send (); }
/// <summary>
/// Recenter the draggable list on the center-most child.
/// </summary>
public void Recenter()
{
if (mDrag == null)
{
mDrag = NGUITools.FindInParents<UIDraggablePanel>(gameObject);
if (mDrag == null)
{
Debug.LogWarning(GetType() + " requires " + typeof(UIDraggablePanel) + " on a parent object in order to work", this);
enabled = false;
return;
}
else
{
mDrag.onDragFinished = OnDragFinished;
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;
int index = -1;
// 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;
index= i;
}
}
isMoved = false;
//if user use sortName,mabe a bug for child index
if(isCenterNext && UICamera.currentTouch != null){
if(UICamera.currentTouch.totalDelta.x > 5.0f){
if(index - 1 >= 0){
closest = trans.GetChild(index - 1);
}
}
else if(UICamera.currentTouch.totalDelta.x < -5.0f)
{
if(index + 1 < trans.childCount){
closest = trans.GetChild(index + 1);
}
}
else{
closest = null;
}
}
if (closest != null)
{
isMoved = true;
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;
if(moveingSound != null && mDrag.gameObject.transform.localPosition != (dt.localPosition - offset)){
// AudioManage.Instance.PlayOneShot(moveingSound);
}
// Spring the panel to this calculated position
SpringPanel.Begin(mDrag.gameObject, dt.localPosition - offset, strength).onFinished = onFinished;
}
else mCenteredObject = null;
}
void Send ()
{
if (string.IsNullOrEmpty(functionName)) return;
if (target == null) target = gameObject;
if (includeChildren)
{
Transform[] transforms = target.GetComponentsInChildren<Transform>();
for (int i = 0, imax = transforms.Length; i < imax; ++i)
{
Transform t = transforms<i>;
t.gameObject.SendMessage(functionName, gameObject, SendMessageOptions.DontRequireReceiver);
}
}
else
{
target.SendMessage(functionName, gameObject, SendMessageOptions.DontRequireReceiver);
}
}
}