整理成功的脚本
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class UIScrollPageEx : MonoBehaviour {
enum ItemIndex
{
Begin = 0, // start第一个
Current = 0,// 当前的
Next = 1, // 下一个
Previous = 2,// 前一个
End = 3,// end最后一个
}
public GameObject dragBox; // BoxCollider - +UIEventListener
public UIWidget itemPrefab; // scrollview - item
public bool wrapItem = false;
public float nextPageThreshold = 0f;// item 翻到下一页的偏移值
public UIBasicSprite tabBgPrefab;// 页签item
public UIBasicSprite tabFg; // 页签亮
public int tabSize = 20;// 页签间隔
public delegate void OnCenterCallback(GameObject centeredObject);
public OnCenterCallback onCenter;// Center事件
public GameObject centeredObject { get { return mCenteredObject; } }// 居中的item的obj
[HideInInspector]
[SerializeField]
protected int mCurPageIndex = 0;
[HideInInspector]
[SerializeField]
protected int mPageCount = 0;
protected UIScrollPageItem[] mItems = new UIScrollPageItem[(int)ItemIndex.End];
protected UIWidget[] mItemWidgets = new UIWidget[(int)ItemIndex.End];// 前一个 当前 后一个
protected List<Transform> mTabs = new List<Transform>();
protected int mItemSize = 0;// item的宽
protected Vector3 mItemOriginalPos;// item的localposition
protected Vector3 mScrollViewOriginalPos;// scrollview的localposition
protected Vector2 mScrollViewOriginalClipOffset;
protected UIScrollView mScrollView;
protected GameObject mCenteredObject;
protected SpringPanel mSpringPanel;
protected bool mIsPanelSpring = false;
bool mIsInit = false;
void Awake()
{
Init();
}
void Init()
{
if (mIsInit)
{
return;
}
mIsInit = true;
if (Application.isPlaying)// app打开的时候
{
mScrollView = GetComponent<UIScrollView>();
UIEventListener lis = UIEventListener.Get(dragBox);
if (lis != null)
{
//lis.onDragStart = OnDragStart;
lis.onDrag += OnDrag;
lis.onDragEnd += OnDragEnd;
lis.onPress += OnPress;
}
if (itemPrefab != null)
{
itemPrefab.gameObject.SetActive(false);
mItemSize = itemPrefab.width;
mItemOriginalPos = itemPrefab.transform.localPosition;
mScrollViewOriginalPos = transform.localPosition;
if (mScrollView != null && mScrollView.panel != null)
{
mScrollViewOriginalClipOffset = mScrollView.panel.clipOffset;
}
mItemWidgets[(int)ItemIndex.Current] = itemPrefab;
//mItemWidgets[(int)ItemIndex.Current].transform.localPosition = curPos;
Vector3 pos = mItemOriginalPos;
pos.x += mItemSize;
mItemWidgets[(int)ItemIndex.Next] = GameObject.Instantiate<UIWidget>(itemPrefab);
mItemWidgets[(int)ItemIndex.Next].transform.parent = itemPrefab.transform.parent;
mItemWidgets[(int)ItemIndex.Next].transform.localPosition = pos;
pos = mItemOriginalPos;
pos.x -= mItemSize;
mItemWidgets[(int)ItemIndex.Previous] = GameObject.Instantiate<UIWidget>(itemPrefab);
mItemWidgets[(int)ItemIndex.Previous].transform.parent = itemPrefab.transform.parent;
mItemWidgets[(int)ItemIndex.Previous].transform.localPosition = pos;
}
if (tabBgPrefab != null)
{
tabBgPrefab.gameObject.SetActive(false);
}
}
}
public void SetPage<T>(int pageCount, int curPageIndex = 0) where T : UIScrollPageItem
{
Init();
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
if (mItemWidgets[i] == null)
{
Debug.LogError("mItemWidgets not init");
return;
}
if (mItems[i] == null)
{
mItems[i] = mItemWidgets[i].gameObject.AddComponent<T>();
mItems[i].index = -1;
}
else
{
if (false == (mItems[i] is T))
{
Component.Destroy(mItems[i]);
mItems[i] = mItemWidgets[i].gameObject.AddComponent<T>();
}
mItems[i].index = -1;
}
}
mPageCount = pageCount;
mCurPageIndex = curPageIndex;
UpdateTabs();
if (pageCount <= 0 || curPageIndex < 0 || curPageIndex >= pageCount)
{
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
mItemWidgets[i].gameObject.SetActive(false);
}
return;
}
mItems[(int)ItemIndex.Current].transform.localPosition = mItemOriginalPos;
UpdateItems();
transform.localPosition = mScrollViewOriginalPos;
if (mScrollView != null && mScrollView.panel != null)
{
mScrollView.panel.clipOffset = mScrollViewOriginalClipOffset;
}
mCenteredObject = mItems[(int)ItemIndex.Current].gameObject;
if (onCenter != null)
{
onCenter(mCenteredObject);
}
//CenterOn(mItems[(int)ItemIndex.Current].transform, true);
}
// 更新页签items
void UpdateTabs()
{
if (mScrollView == null || mScrollView.panel == null || mTabs == null || tabBgPrefab == null || tabBgPrefab.transform.parent == null)
{
return;
}
int tabsCount = mTabs.Count;
if (mPageCount <= tabsCount)
{
for (int i = 0; i < tabsCount; i++)
{
if (mTabs[i] == null) continue;
if (i < mPageCount)
{
mTabs[i].gameObject.SetActive(true);
if (mScrollView.canMoveHorizontally)
{
mTabs[i].localPosition = new Vector3(i * tabSize, 0, 0);
}
else
{
mTabs[i].localPosition = new Vector3(0, -i * tabSize, 0);
}
}
else
{
mTabs[i].gameObject.SetActive(false);
}
}
}
else
{
Transform parentTrans = tabBgPrefab.transform.parent;
int tabIndex = 0;
for (int i = 0; i < mPageCount; i++)
{
if (i < tabsCount)
{
if (mTabs[i] != null)
{
mTabs[i].gameObject.SetActive(true);
if (mScrollView.canMoveHorizontally)
{
mTabs[i].localPosition = new Vector3(tabIndex * tabSize, 0, 0);
}
else
{
mTabs[i].localPosition = new Vector3(0, -tabIndex * tabSize, 0);
}
tabIndex++;
}
}
else
{
if (parentTrans != null)
{
GameObject go = NGUITools.AddChild(parentTrans.gameObject, tabBgPrefab.gameObject);
if (go != null)
{
go.SetActive(true);
mTabs.Add(go.transform);
if (mScrollView.canMoveHorizontally)
{
go.transform.localPosition = new Vector3(tabIndex * tabSize, 0, 0);
}
else
{
go.transform.localPosition = new Vector3(0, -tabIndex * tabSize, 0);
}
go.name = tabIndex.ToString();
tabIndex++;
}
}
}
}
}
int tabPosOffset = 0;
for (int i = 0, iMax = mTabs.Count; i < iMax; i++)
{
if (mTabs[i] != null && mTabs[i].gameObject.activeSelf)
{
tabPosOffset++;
}
}
tabPosOffset *= tabSize;
tabPosOffset /= 2;
Vector3[] corners = mScrollView.panel.worldCorners;
Vector3 panelCenter = (corners[2] + corners[0]) * 0.5f;
Vector3 tabParentPos = tabBgPrefab.transform.parent.position;
if (mScrollView.canMoveHorizontally)
{
tabParentPos.x = panelCenter.x;
}
else
{
tabParentPos.y = panelCenter.y;
}
tabBgPrefab.transform.parent.position = tabParentPos;
tabParentPos = tabBgPrefab.transform.parent.localPosition;
if (mScrollView.canMoveHorizontally)
{
tabParentPos.x = Mathf.Round(tabParentPos.x - tabPosOffset + tabSize / 2); // tab的图片居中显示 偏移多加一半size;
tabParentPos.y = Mathf.Round(tabParentPos.y);
}
else
{
tabParentPos.x = Mathf.Round(tabParentPos.x);
tabParentPos.y = Mathf.Round(tabParentPos.y + tabPosOffset - tabSize / 2);
}
tabParentPos.z = Mathf.Round(tabParentPos.z);
tabBgPrefab.transform.parent.localPosition = tabParentPos;
}
// true-下一页 false-上一页
public void Move(bool nextPage)
{
Transform target = null;
if (nextPage)
{
if (mItems[(int)ItemIndex.Next] != null && mItems[(int)ItemIndex.Next].index >= 0)
{
target = mItems[(int)ItemIndex.Next].transform;
}
}
else
{
if (mItems[(int)ItemIndex.Previous] != null && mItems[(int)ItemIndex.Previous].index >= 0)
{
target = mItems[(int)ItemIndex.Previous].transform;
}
}
if (target != null)
{
CenterOn(target);
MoveItems();
}
}
// 移动Itmes
void MoveItems()
{
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
if (mItems[i] != null && mItems[i].gameObject == mCenteredObject)
{
mCurPageIndex = mItems[i].index;
if (mCurPageIndex < 0 || mCurPageIndex >= mPageCount)
{
// 应该不会出现这种情况;
Debug.LogError("item index error");
break;
}
if (i == (int)ItemIndex.Next)
{
UIScrollPageItem tmpItem = mItems[(int)ItemIndex.Current];
mItems[(int)ItemIndex.Current] = mItems[(int)ItemIndex.Next];
mItems[(int)ItemIndex.Next] = mItems[(int)ItemIndex.Previous];
mItems[(int)ItemIndex.Previous] = tmpItem;
UpdateItems();
}
else if (i == (int)ItemIndex.Previous)
{
UIScrollPageItem tmpItem = mItems[(int)ItemIndex.Current];
mItems[(int)ItemIndex.Current] = mItems[(int)ItemIndex.Previous];
mItems[(int)ItemIndex.Previous] = mItems[(int)ItemIndex.Next];
mItems[(int)ItemIndex.Next] = tmpItem;
UpdateItems();
}
break;
}
}
}
// 刷新当前的Items
void UpdateItems()
{
if (mScrollView == null)
{
return;
}
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
if (mItems[i] == null)
{
Debug.LogError("mItems not init");
return;
}
}
mItems[(int)ItemIndex.Current].index = mCurPageIndex;
//mItems[(int)ItemIndex.Current].transform.localPosition = mItemOriginalPos;
if (mCurPageIndex + 1 >= 0 && mCurPageIndex + 1 < mPageCount)
{
mItems[(int)ItemIndex.Next].index = mCurPageIndex + 1;
SetItemPos(ItemIndex.Next);
}
else
{
if (wrapItem && mPageCount > 1)
{
mItems[(int)ItemIndex.Next].index = 0;
SetItemPos(ItemIndex.Next);
}
else
{
mItems[(int)ItemIndex.Next].index = -1;
}
}
if (mCurPageIndex - 1 >= 0 && mCurPageIndex - 1 < mPageCount)
{
mItems[(int)ItemIndex.Previous].index = mCurPageIndex - 1;
SetItemPos(ItemIndex.Previous);
}
else
{
if (wrapItem && mPageCount > 1)
{
mItems[(int)ItemIndex.Previous].index = mPageCount - 1;
SetItemPos(ItemIndex.Previous);
}
else
{
mItems[(int)ItemIndex.Previous].index = -1;
}
}
SetCurTab();
}
// 刷新当前页签的状态
void SetCurTab()
{
if (tabFg == null)
{
return;
}
if (mTabs == null || mCurPageIndex < 0 || mCurPageIndex >= mTabs.Count || mTabs[mCurPageIndex] == null)
{
tabFg.gameObject.SetActive(false);
return;
}
tabFg.transform.localPosition = mTabs[mCurPageIndex].localPosition;
}
// 设置单个item位置
void SetItemPos(ItemIndex itemIndex)
{
if (ItemIndex.Next != itemIndex && ItemIndex.Previous != itemIndex)
{
return;
}
Vector3 pos = mItems[(int)ItemIndex.Current].transform.localPosition;
if (ItemIndex.Next == itemIndex)
{
if (mScrollView.canMoveHorizontally)
{
pos.x += mItemSize;
}
else
{
pos.y -= mItemSize;
}
}
else if (ItemIndex.Previous == itemIndex)
{
if (mScrollView.canMoveHorizontally)
{
pos.x -= mItemSize;
}
else
{
pos.y += mItemSize;
}
}
mItems[(int)itemIndex].transform.localPosition = pos;
}
void CenterOn(Transform target)
{
if (mScrollView != null && mScrollView.panel != null)
{
Vector3[] corners = mScrollView.panel.worldCorners;
Vector3 panelCenter = (corners[2] + corners[0]) * 0.5f;
CenterOn(target, panelCenter);
}
}
void CenterOn(Transform target, Vector3 panelCenter, bool immediately = false)
{
if (target != null && mScrollView != null && mScrollView.panel != null)
{
Transform panelTrans = mScrollView.panel.cachedTransform;
mCenteredObject = target.gameObject;
// Figure out the difference between the chosen child and the panel's center in local coordinates
Vector3 cp = panelTrans.InverseTransformPoint(target.position);
Vector3 cc = panelTrans.InverseTransformPoint(panelCenter);
Vector3 localOffset = cp - cc;
// Offset shouldn't occur if blocked
if (!mScrollView.canMoveHorizontally) localOffset.x = 0f;
if (!mScrollView.canMoveVertically) localOffset.y = 0f;
localOffset.z = 0f;
if (immediately)
{
mScrollView.panel.cachedGameObject.transform.localPosition = panelTrans.localPosition - localOffset;
}
else
{
// Spring the panel to this calculated position
if (mSpringPanel == null)
{
mSpringPanel = SpringPanel.Begin(mScrollView.panel.cachedGameObject, panelTrans.localPosition - localOffset, 8);
mSpringPanel.onFinished = OnSpringFinished;
}
else
{
mSpringPanel.target = panelTrans.localPosition - localOffset;
mSpringPanel.enabled = true;
}
mIsPanelSpring = true;
}
}
else
{
mCenteredObject = null;
}
// Notify the listener
if (onCenter != null)
{
onCenter(mCenteredObject);
}
}
void OnSpringFinished()
{
mIsPanelSpring = false;
}
void OnDrag(GameObject go, Vector2 delta)
{
if (mScrollView != null)
{
mScrollView.Drag();
}
}
void OnDragStart(GameObject go)
{
// if (mScrollView == null)
// {
// return;
// }
// mScrollViewStartPos = mScrollView.transform.localPosition;
}
void OnDragEnd(GameObject go)
{
Recenter();
}
void OnPress(GameObject go, bool pressed)
{
if (mScrollView != null)
{
mScrollView.Press(pressed);
}
if (!pressed)
{
if (mSpringPanel != null && mIsPanelSpring && !mSpringPanel.enabled)
{
mSpringPanel.enabled = true;
}
}
}
// scrollview拖拽结果 - 刷新ui
void Recenter()
{
if (mScrollView == null || mScrollView.panel == null || itemPrefab == null)
{
return;
}
Transform trans = itemPrefab.transform.parent;
if (trans.childCount == 0)
{
return;
}
// Calculate the panel's center in world coordinates
Vector3[] corners = mScrollView.panel.worldCorners;
Vector3 panelCenter = (corners[2] + corners[0]) * 0.5f;
// Offset this value by the momentum
Vector3 momentum = mScrollView.currentMomentum * mScrollView.momentumAmount;
Vector3 moveDelta = NGUIMath.SpringDampen(ref momentum, 9f, 2f);
Vector3 pickingPoint = panelCenter - moveDelta * 0.01f; // Magic number based on what "feels right"
float min = float.MaxValue;
Transform closest = null;
int index = 0;
//int ignoredIndex = 0;
List<Transform> list = null;
// Determine the closest child
for (int i = 0, imax = trans.childCount, ii = 0; i < imax; ++i)
{
Transform t = trans.GetChild(i);
if (list == null)
{
list = new List<Transform>();
}
list.Add(t);
if (!t.gameObject.activeInHierarchy) continue;
float sqrDist = Vector3.SqrMagnitude(t.position - pickingPoint);
if (sqrDist < min)
{
min = sqrDist;
closest = t;
index = i;
//ignoredIndex = ii;
}
++ii;
}
// If we have a touch in progress and the next page threshold set
if (nextPageThreshold > 0f && UICamera.currentTouch != null)
{
// If we're still on the same object
if (mCenteredObject != null && mCenteredObject.transform == (list != null ? list[index] : trans.GetChild(index)))
{
Vector3 totalDelta = UICamera.currentTouch.totalDelta;
totalDelta = transform.rotation * totalDelta;
float delta = 0f;
switch (mScrollView.movement)
{
case UIScrollView.Movement.Horizontal:
{
delta = totalDelta.x;
break;
}
case UIScrollView.Movement.Vertical:
{
delta = totalDelta.y;
break;
}
default:
{
delta = totalDelta.magnitude;
break;
}
}
if (Mathf.Abs(delta) > nextPageThreshold)
{
if (delta > nextPageThreshold)
{
if (mScrollView.canMoveHorizontally)
{
// Previous page
if (mItems[(int)ItemIndex.Previous] != null && mItems[(int)ItemIndex.Previous].index >= 0)
{
closest = mItems[(int)ItemIndex.Previous].transform;
}
}
else
{
// Next page
if (mItems[(int)ItemIndex.Next] != null && mItems[(int)ItemIndex.Next].index >= 0)
{
closest = mItems[(int)ItemIndex.Next].transform;
}
}
}
else if (delta < -nextPageThreshold)
{
if (mScrollView.canMoveHorizontally)
{
// Next page
if (mItems[(int)ItemIndex.Next] != null && mItems[(int)ItemIndex.Next].index >= 0)
{
closest = mItems[(int)ItemIndex.Next].transform;
}
}
else
{
// Previous page
if (mItems[(int)ItemIndex.Previous] != null && mItems[(int)ItemIndex.Previous].index >= 0)
{
closest = mItems[(int)ItemIndex.Previous].transform;
}
}
}
}
}
}
CenterOn(closest, panelCenter);
MoveItems();
}
}
使用方法
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using PBClientClass;
using CommonEnum;
using System;
public class UIPayTest : UIPanelBase {
UIPayTestView _View;
UIScrollPageEx _UIScrollPageEx;
Transform _TabObjs;
bool _ClickItem = false;
void Awake()
{
_View = gameObject.AddComponent<UIPayTestView>();
_UIScrollPageEx = _View.Anchor_scrollview_UIScrollPageEx;
_TabObjs = _View.objs_tabs_Transform;
UITools.AddOnclick(_View.btns_pre_btn_UIButton, OnPreBtnClicked);
UITools.AddOnclick(_View.btns_next_btn_UIButton, OnNextBtnClicked);
if (_UIScrollPageEx != null)
{
_UIScrollPageEx.onCenter = OnCenterScrollPage;
if (_UIScrollPageEx.dragBox != null)
{
UIEventListener lis = UIEventListener.Get(_UIScrollPageEx.dragBox);
if (lis != null)
{
lis.onDragStart += OnDragStart;
lis.onPress += OnPress;
}
}
}
}
public override void OnShow(params object[] paramsList)
{
// FrameRateProcesser.Instance.TargetFramerate = FrameRateProcesser.HighRate;
// Application.targetFrameRate = FrameRateProcesser.HighRate;
SetItems();
}
void SetItems()
{
int count = 10;
if (_UIScrollPageEx != null)
{
_UIScrollPageEx.SetPage<UIPayTestItem>(count);
}
UITools.setActive(_TabObjs, count > 0);
}
// 开始拖拽
void OnDragStart(GameObject go)
{
_ClickItem = false;
}
// 按下item
void OnPress(GameObject go, bool pressed)
{
if (pressed)
{
_ClickItem = true;
}
else
{
if (_ClickItem)
{
if (_UIScrollPageEx != null && _UIScrollPageEx.centeredObject != null)
{
UIPayTestItem item = _UIScrollPageEx.centeredObject.GetComponent<UIPayTestItem>();
if (item != null)
{
}
}
}
}
}
// 当前居中事件
void OnCenterScrollPage(GameObject go)
{
// CancelInvoke("MovePage");
// Invoke("MovePage", ConstValueProvider.Instance.GetFloatValueEx("UIGiftPageMoveTime", 10));
}
// 上一个
void OnPreBtnClicked()
{
if (_UIScrollPageEx != null)
{
_UIScrollPageEx.Move(false);
}
}
// 下一个
void OnNextBtnClicked()
{
if (_UIScrollPageEx != null)
{
_UIScrollPageEx.Move(true);
}
}
}
public class UIPayTestItem : UIScrollPageItem
{
public override void OnInitItem()
{
}
}
原始的脚本
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[ExecuteInEditMode]
[RequireComponent(typeof(UIPanel))]
[RequireComponent(typeof(UIScrollView))]
public class UIScrollPage : MonoBehaviour
{
public GameObject dragBox;
public UIWidget itemPrefab;
public bool wrapItem = false;
public float nextPageThreshold = 0f;
public UIBasicSprite tabBgPrefab;
public UIBasicSprite tabFg;
public int tabSize = 20;
public delegate void OnCenterCallback(GameObject centeredObject);
public OnCenterCallback onCenter;
public GameObject centeredObject { get { return mCenteredObject; } }
[HideInInspector]
[SerializeField]
protected int mCurPageIndex = 0;
[HideInInspector]
[SerializeField]
protected int mPageCount = 0;
private enum ItemIndex
{
Begin = 0,
Current = 0,
Next = 1,
Previous = 2,
End = 3,
}
protected UIScrollPageItem[] mItems = new UIScrollPageItem[(int)ItemIndex.End];
protected UIWidget[] mItemWidgets = new UIWidget[(int)ItemIndex.End];
protected List<Transform> mTabs = new List<Transform>();
protected int mItemSize = 0;
protected Vector3 mItemOriginalPos;
protected Vector3 mScrollViewOriginalPos;
protected Vector2 mScrollViewOriginalClipOffset;
protected UIScrollView mScrollView;
protected GameObject mCenteredObject;
protected SpringPanel mSpringPanel;
protected bool mIsInit = false;
protected bool mIsPanelSpring = false;
void Awake()
{
Init();
}
private void Init()
{
if (mIsInit)
{
return;
}
mIsInit = true;
if (Application.isPlaying)
{
mScrollView = GetComponent<UIScrollView>();
UIEventListener lis = UIEventListener.Get(dragBox);
if (lis != null)
{
//lis.onDragStart = OnDragStart;
lis.onDrag += OnDrag;
lis.onDragEnd += OnDragEnd;
lis.onPress += OnPress;
}
if (itemPrefab != null)
{
itemPrefab.gameObject.SetActive(false);
mItemSize = itemPrefab.width;
mItemOriginalPos = itemPrefab.transform.localPosition;
mScrollViewOriginalPos = transform.localPosition;
if (mScrollView != null && mScrollView.panel != null)
{
mScrollViewOriginalClipOffset = mScrollView.panel.clipOffset;
}
mItemWidgets[(int)ItemIndex.Current] = itemPrefab;
//mItemWidgets[(int)ItemIndex.Current].transform.localPosition = curPos;
Vector3 pos = mItemOriginalPos;
pos.x += mItemSize;
mItemWidgets[(int)ItemIndex.Next] = GameObject.Instantiate<UIWidget>(itemPrefab);
mItemWidgets[(int)ItemIndex.Next].transform.parent = itemPrefab.transform.parent;
mItemWidgets[(int)ItemIndex.Next].transform.localPosition = pos;
pos = mItemOriginalPos;
pos.x -= mItemSize;
mItemWidgets[(int)ItemIndex.Previous] = GameObject.Instantiate<UIWidget>(itemPrefab);
mItemWidgets[(int)ItemIndex.Previous].transform.parent = itemPrefab.transform.parent;
mItemWidgets[(int)ItemIndex.Previous].transform.localPosition = pos;
}
if (tabBgPrefab != null)
{
tabBgPrefab.gameObject.SetActive(false);
}
}
}
public void Move(bool nextPage)
{
Transform target = null;
if (nextPage)
{
if (mItems[(int)ItemIndex.Next] != null && mItems[(int)ItemIndex.Next].index >= 0)
{
target = mItems[(int)ItemIndex.Next].transform;
}
}
else
{
if (mItems[(int)ItemIndex.Previous] != null && mItems[(int)ItemIndex.Previous].index >= 0)
{
target = mItems[(int)ItemIndex.Previous].transform;
}
}
if (target != null)
{
CenterOn(target);
MoveItems();
}
}
public void SetPage<T>(int pageCount, int curPageIndex = 0) where T : UIScrollPageItem
{
Init();
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
if (mItemWidgets[i] == null)
{
Debug.LogError("mItemWidgets not init");
return;
}
if (mItems[i] == null)
{
mItems[i] = mItemWidgets[i].gameObject.AddComponent<T>();
mItems[i].index = -1;
}
else
{
if (false == (mItems[i] is T))
{
Component.Destroy(mItems[i]);
mItems[i] = mItemWidgets[i].gameObject.AddComponent<T>();
}
mItems[i].index = -1;
}
}
mPageCount = pageCount;
mCurPageIndex = curPageIndex;
UpdateTabs();
if (pageCount <= 0 || curPageIndex < 0 || curPageIndex >= pageCount)
{
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
mItemWidgets[i].gameObject.SetActive(false);
}
return;
}
mItems[(int)ItemIndex.Current].transform.localPosition = mItemOriginalPos;
UpdateItems();
transform.localPosition = mScrollViewOriginalPos;
if (mScrollView != null && mScrollView.panel != null)
{
mScrollView.panel.clipOffset = mScrollViewOriginalClipOffset;
}
mCenteredObject = mItems[(int)ItemIndex.Current].gameObject;
if (onCenter != null)
{
onCenter(mCenteredObject);
}
//CenterOn(mItems[(int)ItemIndex.Current].transform, true);
}
private void UpdateItems()
{
if (mScrollView == null)
{
return;
}
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
if (mItems[i] == null)
{
Debug.LogError("mItems not init");
return;
}
}
mItems[(int)ItemIndex.Current].index = mCurPageIndex;
//mItems[(int)ItemIndex.Current].transform.localPosition = mItemOriginalPos;
if (mCurPageIndex + 1 >= 0 && mCurPageIndex + 1 < mPageCount)
{
mItems[(int)ItemIndex.Next].index = mCurPageIndex + 1;
SetItemPos(ItemIndex.Next);
}
else
{
if (wrapItem && mPageCount > 1)
{
mItems[(int)ItemIndex.Next].index = 0;
SetItemPos(ItemIndex.Next);
}
else
{
mItems[(int)ItemIndex.Next].index = -1;
}
}
if (mCurPageIndex - 1 >= 0 && mCurPageIndex - 1 < mPageCount)
{
mItems[(int)ItemIndex.Previous].index = mCurPageIndex - 1;
SetItemPos(ItemIndex.Previous);
}
else
{
if (wrapItem && mPageCount > 1)
{
mItems[(int)ItemIndex.Previous].index = mPageCount - 1;
SetItemPos(ItemIndex.Previous);
}
else
{
mItems[(int)ItemIndex.Previous].index = -1;
}
}
SetCurTab();
}
private void SetItemPos(ItemIndex itemIndex)
{
if (ItemIndex.Next != itemIndex && ItemIndex.Previous != itemIndex)
{
return;
}
Vector3 pos = mItems[(int)ItemIndex.Current].transform.localPosition;
if (ItemIndex.Next == itemIndex)
{
if (mScrollView.canMoveHorizontally)
{
pos.x += mItemSize;
}
else
{
pos.y -= mItemSize;
}
}
else if (ItemIndex.Previous == itemIndex)
{
if (mScrollView.canMoveHorizontally)
{
pos.x -= mItemSize;
}
else
{
pos.y += mItemSize;
}
}
mItems[(int)itemIndex].transform.localPosition = pos;
}
private void UpdateTabs()
{
if (mScrollView == null || mScrollView.panel == null || mTabs == null || tabBgPrefab == null || tabBgPrefab.transform.parent == null)
{
return;
}
int tabsCount = mTabs.Count;
if (mPageCount <= tabsCount)
{
for (int i = 0; i < tabsCount; i++)
{
if (mTabs[i] == null) continue;
if (i < mPageCount)
{
mTabs[i].gameObject.SetActive(true);
if (mScrollView.canMoveHorizontally)
{
mTabs[i].localPosition = new Vector3(i * tabSize, 0, 0);
}
else
{
mTabs[i].localPosition = new Vector3(0, -i * tabSize, 0);
}
}
else
{
mTabs[i].gameObject.SetActive(false);
}
}
}
else
{
Transform parentTrans = tabBgPrefab.transform.parent;
int tabIndex = 0;
for (int i = 0; i < mPageCount; i++)
{
if (i < tabsCount)
{
if (mTabs[i] != null)
{
mTabs[i].gameObject.SetActive(true);
if (mScrollView.canMoveHorizontally)
{
mTabs[i].localPosition = new Vector3(tabIndex * tabSize, 0, 0);
}
else
{
mTabs[i].localPosition = new Vector3(0, -tabIndex * tabSize, 0);
}
tabIndex++;
}
}
else
{
if (parentTrans != null)
{
GameObject go = NGUITools.AddChild(parentTrans.gameObject, tabBgPrefab.gameObject);
if (go != null)
{
go.SetActive(true);
mTabs.Add(go.transform);
if (mScrollView.canMoveHorizontally)
{
go.transform.localPosition = new Vector3(tabIndex * tabSize, 0, 0);
}
else
{
go.transform.localPosition = new Vector3(0, -tabIndex * tabSize, 0);
}
go.name = tabIndex.ToString();
tabIndex++;
}
}
}
}
}
int tabPosOffset = 0;
for (int i = 0, iMax = mTabs.Count; i < iMax; i++)
{
if (mTabs[i] != null && mTabs[i].gameObject.activeSelf)
{
tabPosOffset++;
}
}
tabPosOffset *= tabSize;
tabPosOffset /= 2;
Vector3[] corners = mScrollView.panel.worldCorners;
Vector3 panelCenter = (corners[2] + corners[0]) * 0.5f;
Vector3 tabParentPos = tabBgPrefab.transform.parent.position;
if (mScrollView.canMoveHorizontally)
{
tabParentPos.x = panelCenter.x;
}
else
{
tabParentPos.y = panelCenter.y;
}
tabBgPrefab.transform.parent.position = tabParentPos;
tabParentPos = tabBgPrefab.transform.parent.localPosition;
if (mScrollView.canMoveHorizontally)
{
tabParentPos.x = Mathf.Round(tabParentPos.x - tabPosOffset + tabSize / 2); // tab的图片居中显示 偏移多加一半size;
tabParentPos.y = Mathf.Round(tabParentPos.y);
}
else
{
tabParentPos.x = Mathf.Round(tabParentPos.x);
tabParentPos.y = Mathf.Round(tabParentPos.y + tabPosOffset - tabSize / 2);
}
tabParentPos.z = Mathf.Round(tabParentPos.z);
tabBgPrefab.transform.parent.localPosition = tabParentPos;
}
private void SetCurTab()
{
if (tabFg == null)
{
return;
}
if (mTabs == null || mCurPageIndex < 0 || mCurPageIndex >= mTabs.Count || mTabs[mCurPageIndex] == null)
{
tabFg.gameObject.SetActive(false);
return;
}
tabFg.transform.localPosition = mTabs[mCurPageIndex].localPosition;
}
//private void OnDragStart(GameObject go)
//{
// if (mScrollView == null)
// {
// return;
// }
// mScrollViewStartPos = mScrollView.transform.localPosition;
//}
private void OnDrag(GameObject go, Vector2 delta)
{
if (mScrollView != null)
{
mScrollView.Drag();
}
}
private void OnDragEnd(GameObject go)
{
Recenter();
}
private void OnPress(GameObject go, bool pressed)
{
if (mScrollView != null)
{
mScrollView.Press(pressed);
}
if (!pressed)
{
if (mSpringPanel != null && mIsPanelSpring && !mSpringPanel.enabled)
{
mSpringPanel.enabled = true;
}
}
}
private void OnDisable()
{
if (mSpringPanel != null)
{
mSpringPanel.enabled = false;
}
}
private void Recenter()
{
if (mScrollView == null || mScrollView.panel == null || itemPrefab == null)
{
return;
}
Transform trans = itemPrefab.transform.parent;
if (trans.childCount == 0)
{
return;
}
// Calculate the panel's center in world coordinates
Vector3[] corners = mScrollView.panel.worldCorners;
Vector3 panelCenter = (corners[2] + corners[0]) * 0.5f;
// Offset this value by the momentum
Vector3 momentum = mScrollView.currentMomentum * mScrollView.momentumAmount;
Vector3 moveDelta = NGUIMath.SpringDampen(ref momentum, 9f, 2f);
Vector3 pickingPoint = panelCenter - moveDelta * 0.01f; // Magic number based on what "feels right"
float min = float.MaxValue;
Transform closest = null;
int index = 0;
//int ignoredIndex = 0;
List<Transform> list = null;
// Determine the closest child
for (int i = 0, imax = trans.childCount, ii = 0; i < imax; ++i)
{
Transform t = trans.GetChild(i);
if (list == null)
{
list = new List<Transform>();
}
list.Add(t);
if (!t.gameObject.activeInHierarchy) continue;
float sqrDist = Vector3.SqrMagnitude(t.position - pickingPoint);
if (sqrDist < min)
{
min = sqrDist;
closest = t;
index = i;
//ignoredIndex = ii;
}
++ii;
}
// If we have a touch in progress and the next page threshold set
if (nextPageThreshold > 0f && UICamera.currentTouch != null)
{
// If we're still on the same object
if (mCenteredObject != null && mCenteredObject.transform == (list != null ? list[index] : trans.GetChild(index)))
{
Vector3 totalDelta = UICamera.currentTouch.totalDelta;
totalDelta = transform.rotation * totalDelta;
float delta = 0f;
switch (mScrollView.movement)
{
case UIScrollView.Movement.Horizontal:
{
delta = totalDelta.x;
break;
}
case UIScrollView.Movement.Vertical:
{
delta = totalDelta.y;
break;
}
default:
{
delta = totalDelta.magnitude;
break;
}
}
if (Mathf.Abs(delta) > nextPageThreshold)
{
if (delta > nextPageThreshold)
{
if (mScrollView.canMoveHorizontally)
{
// Previous page
if (mItems[(int)ItemIndex.Previous] != null && mItems[(int)ItemIndex.Previous].index >= 0)
{
closest = mItems[(int)ItemIndex.Previous].transform;
}
}
else
{
// Next page
if (mItems[(int)ItemIndex.Next] != null && mItems[(int)ItemIndex.Next].index >= 0)
{
closest = mItems[(int)ItemIndex.Next].transform;
}
}
}
else if (delta < -nextPageThreshold)
{
if (mScrollView.canMoveHorizontally)
{
// Next page
if (mItems[(int)ItemIndex.Next] != null && mItems[(int)ItemIndex.Next].index >= 0)
{
closest = mItems[(int)ItemIndex.Next].transform;
}
}
else
{
// Previous page
if (mItems[(int)ItemIndex.Previous] != null && mItems[(int)ItemIndex.Previous].index >= 0)
{
closest = mItems[(int)ItemIndex.Previous].transform;
}
}
}
}
}
}
CenterOn(closest, panelCenter);
MoveItems();
}
private void CenterOn(Transform target, Vector3 panelCenter, bool immediately = false)
{
if (target != null && mScrollView != null && mScrollView.panel != null)
{
Transform panelTrans = mScrollView.panel.cachedTransform;
mCenteredObject = target.gameObject;
// Figure out the difference between the chosen child and the panel's center in local coordinates
Vector3 cp = panelTrans.InverseTransformPoint(target.position);
Vector3 cc = panelTrans.InverseTransformPoint(panelCenter);
Vector3 localOffset = cp - cc;
// Offset shouldn't occur if blocked
if (!mScrollView.canMoveHorizontally) localOffset.x = 0f;
if (!mScrollView.canMoveVertically) localOffset.y = 0f;
localOffset.z = 0f;
if (immediately)
{
mScrollView.panel.cachedGameObject.transform.localPosition = panelTrans.localPosition - localOffset;
}
else
{
// Spring the panel to this calculated position
if (mSpringPanel == null)
{
mSpringPanel = SpringPanel.Begin(mScrollView.panel.cachedGameObject, panelTrans.localPosition - localOffset, 8);
mSpringPanel.onFinished = OnSpringFinished;
}
else
{
mSpringPanel.target = panelTrans.localPosition - localOffset;
mSpringPanel.enabled = true;
}
mIsPanelSpring = true;
}
}
else
{
mCenteredObject = null;
}
// Notify the listener
if (onCenter != null)
{
onCenter(mCenteredObject);
}
}
private void OnSpringFinished()
{
mIsPanelSpring = false;
}
private void CenterOn(Transform target)
{
if (mScrollView != null && mScrollView.panel != null)
{
Vector3[] corners = mScrollView.panel.worldCorners;
Vector3 panelCenter = (corners[2] + corners[0]) * 0.5f;
CenterOn(target, panelCenter);
}
}
private void MoveItems()
{
for (int i = (int)ItemIndex.Begin; i < (int)ItemIndex.End; i++)
{
if (mItems[i] != null && mItems[i].gameObject == mCenteredObject)
{
mCurPageIndex = mItems[i].index;
if (mCurPageIndex < 0 || mCurPageIndex >= mPageCount)
{
// 应该不会出现这种情况;
Debug.LogError("item index error");
break;
}
if (i == (int)ItemIndex.Next)
{
UIScrollPageItem tmpItem = mItems[(int)ItemIndex.Current];
mItems[(int)ItemIndex.Current] = mItems[(int)ItemIndex.Next];
mItems[(int)ItemIndex.Next] = mItems[(int)ItemIndex.Previous];
mItems[(int)ItemIndex.Previous] = tmpItem;
UpdateItems();
}
else if (i == (int)ItemIndex.Previous)
{
UIScrollPageItem tmpItem = mItems[(int)ItemIndex.Current];
mItems[(int)ItemIndex.Current] = mItems[(int)ItemIndex.Previous];
mItems[(int)ItemIndex.Previous] = mItems[(int)ItemIndex.Next];
mItems[(int)ItemIndex.Next] = tmpItem;
UpdateItems();
}
break;
}
}
}
//private void OnSpringFinished()
//{
//}
}
public abstract class UIScrollPageItem : MonoBehaviour
{
private int mIndex = int.MaxValue;
private int mOldIndex = int.MaxValue;
public int oldIndex
{
get
{
return mOldIndex;
}
}
public int index
{
get
{
return mIndex;
}
set
{
if (mIndex != value)
{
mOldIndex = mIndex;
mIndex = value;
name = mIndex.ToString();
if (-1 == mIndex)
{
gameObject.SetActive(false);
}
else
{
OnInitItem();
gameObject.SetActive(true);
}
}
}
}
public abstract void OnInitItem();
}
using UnityEngine;
using UnityEditor;
//[CanEditMultipleObjects]
[CustomEditor(typeof(UIScrollPage))]
public class UIScrollPageInspector : Editor
{
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUI.BeginDisabledGroup(true);// (Application.isPlaying);
NGUIEditorTools.DrawProperty("Current Page Index", serializedObject, "mCurPageIndex");
NGUIEditorTools.DrawProperty("Page Count", serializedObject, "mPageCount");
EditorGUI.EndDisabledGroup();
serializedObject.ApplyModifiedProperties();
DrawDefaultInspector();
}
}
使用方法
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using PBClientClass;
using CommonEnum;
using System;
public class UIPay : UIPanelBase
{
private Transform _GuideTrans = null;
private UIScrollPage _UIScrollPage = null;
private GameObject _TabObjs = null;
private bool _CanOpenRewardUI = false;
void Awake()
{
UITools.AddOnclick(ObjectCommon.GetChildComponent<UIButton>(gameObject, "Anchor/border/closeBtn"), CloseSelf);
UITools.AddOnclick(ObjectCommon.GetChildComponent<UIButton>(gameObject, "Anchor/left_objs/btns/pre_btn"), OnPreButtonClicked);
UITools.AddOnclick(ObjectCommon.GetChildComponent<UIButton>(gameObject, "Anchor/left_objs/btns/next_btn"), OnNextButtonClicked);
_TabObjs = ObjectCommon.GetChild(gameObject, "Anchor/left_objs");
_UIScrollPage = ObjectCommon.GetChildComponent<UIScrollPage>(gameObject, "Anchor/left_scrollview");
if (_UIScrollPage != null)
{
_UIScrollPage.onCenter = OnCenterScrollPage;
if (_UIScrollPage.dragBox != null)
{
UIEventListener lis = UIEventListener.Get(_UIScrollPage.dragBox);
if (lis != null)
{
lis.onDragStart += OnDragStart;
lis.onPress += OnPress;
}
}
}
}
public override void OnRemove()
{
}
public override void OnShow(params object[] paramsList)
{
SetGiftBagUI();
}
public override void OnClose()
{
CancelInvoke();
}
private void OnGetGiftBagInfos(ClientEvent eve)
{
SetGiftBagUI();
}
private void SetGiftBagUI()
{
int giftBagCount = PayManager.Instance.GetGiftBagCount();
if (_UIScrollPage != null)
{
_UIScrollPage.SetPage<UIPayActivityItem>(giftBagCount);
}
UITools.setActive(_TabObjs, giftBagCount > 0);
}
private void OnCenterScrollPage(GameObject go)
{
CancelInvoke("MovePage");// 每隔几秒
Invoke("MovePage", ConstValueProvider.Instance.GetFloatValueEx("UIGiftPageMoveTime", 10));
}
private void MovePage()
{
if (_UIScrollPage != null)
{
_UIScrollPage.Move(true);
}
}
private void OnPreButtonClicked()
{
if (_UIScrollPage != null)
{
_UIScrollPage.Move(false);
}
}
void OnNextButtonClicked()
{
MovePage();
}
void OnPress(GameObject go, bool pressed)
{
//Debug.Log("OnPress " + pressed);
if (pressed)
{
_CanOpenRewardUI = true;
}
else
{
if (_CanOpenRewardUI)
{
if (_UIScrollPage != null && _UIScrollPage.centeredObject != null)
{
UIPayActivityItem item = _UIScrollPage.centeredObject.GetComponent<UIPayActivityItem>();
if (item != null)
{
}
}
}
}
}
private void OnDragStart(GameObject go)
{
_CanOpenRewardUI = false;
}
}
using UnityEngine;
using System.Collections;
using PBClientClass;
using CommonEnum;
public class UIPayActivityItem : UIScrollPageItem
{
bool _IsInit = false;
GiftBagInfo _Info;
void Init()
{
if (_IsInit)
{
return;
}
_IsInit = true;
}
void OnEnable()
{
// 监听事件事件
}
void OnDisable()
{
//移除事件
}
public override void OnInitItem()
{
SetItem();
}
void SetItem()
{
Init();
_Info = PayManager.Instance.GetGiftBagInfo(index);
if (_Info == null || _Info.giftBagData == null)
{
return;
}
// 刷新ui
}
}