//NGUI............................................................
using System; using UnityEngine; using System.Collections; public class ScrollViewTurnPage : MonoBehaviour { [Header("一页的宽度,一般就是ScrollView的宽度")] [SerializeField] private int m_pageWidth &#61; 600; [Range(5.0f, 55.0f)] [SerializeField] private int m_springStrength &#61; 35; private int m_totalPages &#61; 4; //固定的时候&#xff0c;写的页数 [Header("列数")] [SerializeField] private int m_columns &#61; 4; [Header("行数")] [SerializeField] private int m_row &#61; 3; #region Public Interface public void PreviousPage() { if (m_bHorizontal) { if (m_currPage > 1) Page(m_pageWidth); } else { if (m_currPage } } public void NextPage() { if (m_bHorizontal) { if (m_currPage } else { if (m_currPage > 1) Page(-m_pageWidth); } } public int CurrentPage { get { return m_currPage; } } public int TotalPages { get { return m_totalPages; } set { m_totalPages &#61; value; } } public int OnePageItemsMaxNum { get { return m_columns * m_row; } } public int ItemColumns { get { return m_columns; } } public int PageWidth { get { return m_pageWidth; } } #endregion #region private interface private int m_currPage &#61; 1; private UIScrollView m_scrollView &#61; null; private float m_nowLocation &#61; 0; private bool m_bDrag &#61; false; private bool m_bSpringMove &#61; false; private SpringPanel m_springPanel &#61; null; private bool m_bHorizontal &#61; true; void Awake() { m_scrollView &#61; gameObject.GetComponent(); if (m_scrollView &#61;&#61; null) m_scrollView &#61; gameObject.AddComponent(); m_springPanel &#61; GetComponent(); if (m_springPanel &#61;&#61; null) m_springPanel &#61; gameObject.AddComponent(); m_springPanel.enabled &#61; true; m_scrollView.onDragStarted &#61; OnDragStarted; m_scrollView.onMomentumMove &#61; onMomentumMove; m_scrollView.onStoppedMoving &#61; onStoppedMoving; m_scrollView.onDragFinished &#61; onDragFinished; m_bHorizontal &#61; m_scrollView.movement &#61;&#61; UIScrollView.Movement.Horizontal ? true : false; onStoppedMoving(); } void onDragFinished() { onMomentumMove(); } void OnDragStarted() { m_bDrag &#61; false; SetNowLocation(); } void onMomentumMove() { if (m_bDrag) return; Vector3 v3 &#61; transform.localPosition; float value &#61; 0; if (m_bHorizontal) { value &#61; m_nowLocation - v3.x; //if (Mathf.Abs(value) if (value > 0) { if (m_currPage } else { if (m_currPage > 1) Page(m_pageWidth); } } else { value &#61; m_nowLocation - v3.y; //if (Mathf.Abs(value) if (value > 0) { if (m_currPage > 1) Page(-m_pageWidth); } else { if (m_currPage } } } void Page(float value) { m_bSpringMove &#61; true; m_bDrag &#61; true; //m_springPanel &#61; GetComponent(); //if (m_springPanel &#61;&#61; null) m_springPanel &#61; gameObject.AddComponent(); m_springPanel.enabled &#61; false; Vector3 pos &#61; m_springPanel.target; pos &#61; m_bHorizontal ? new Vector3(pos.x &#43; value, pos.y, pos.z) : new Vector3(pos.x, pos.y &#43; value, pos.z); if (!SetIndexPage(pos)) return; SpringPanel.Begin(gameObject, pos, m_springStrength).strength &#61; 10.0f; m_springPanel.onFinished &#61; SpringPanleMoveEnd; //Debug.Log("current Page &#61;&#61;" &#43; m_currPage); } void SpringPanleMoveEnd() { m_bSpringMove &#61; false; //重新定位 } void onStoppedMoving() { m_bDrag &#61; false; SetNowLocation(); } void SetNowLocation() { if (m_bHorizontal) { m_nowLocation &#61; gameObject.transform.localPosition.x; } else { m_nowLocation &#61; gameObject.transform.localPosition.y; } } bool SetIndexPage(Vector3 v3) { float value &#61; m_bHorizontal ? v3.x : v3.y; //if (m_bHorizontal) //{ // if (value > 0 || value <(m_totalPages) * -m_pageWidth) return false; //} //else //{ // if (value <0 || value > (m_totalPages - 1) * m_pageWidth) return false; //} value &#61; Mathf.Abs(value); m_currPage &#61; (int) (value / m_pageWidth) &#43; 1; return true; } #endregion }
简单的实现了下NGUI的上下翻页。有两个接口&#xff0c;分别是上一页和下一页。
用法如下。
如上图&#xff0c;第一个参数为 Page的宽或高&#xff0c;具体由你的滑动组件设定的方向定。
第二个参数为滑动系数&#xff0c;即&#xff0c;滑动了多远就翻页
第三个参数为总页数。
依赖组件。UIScrollView&#xff0c;UICenterOnChild。
脚本和Scroll一起
分页父物体绑上居中脚本。为Scroll的子物体
这个基本功能没问题。但是有一个小缺陷。就是Panel的坐标必须为中心点。如果需要位移需要再加一个父物体。让滑动组件依赖的Panel的相对坐标都为0.
原因是因为我用的坐标去计算的当前页。大家如果有空。可以改为偏移量就能解决这问题。
因为我也用不上这个。这个是写给学员参考的。所以就懒得改了。大家需要的改的话。可以自行修改。
最后。上脚本。
using UnityEngine ; using System . Collections ; public class YouKeTurnPage : MonoBehaviour { /// /// 每页宽度(游-客-学-院) /// public float pageWidth ; /// /// 翻页力度(游.客.学.院) /// public int EffortsFlip &#61; 50 ; /// /// 总页数 /// public int pageNums &#61; 0 ; /// /// 当前所在页 /// public int pageIndex { get { return mPageIndex ; } } /// /// 当前所在页 /// private int mPageIndex &#61; 1 ; private UIScrollView mScrollView &#61; null ; private float nowLocation &#61; 0 ; private bool isDrag &#61; false ; private bool isSpringMove &#61; false ; private SpringPanel mSp &#61; null ; private bool isHorizontal &#61; true ; void Awake () { mScrollView &#61; gameObject . GetComponent (); if ( mScrollView &#61;&#61; null ) { mScrollView &#61; gameObject . AddComponent (); } mScrollView . onDragStarted &#61; OnDragStarted ; mScrollView . onMomentumMove &#61; onMomentumMove ; mScrollView . onStoppedMoving &#61; onStoppedMoving ; if ( mScrollView . movement &#61;&#61; UIScrollView . Movement . Horizontal ) { isHorizontal &#61; true ; } else { isHorizontal &#61; false ; } onStoppedMoving (); } void OnDragStarted () { isDrag &#61; false ; SetNowLocation (); } void onMomentumMove () { if ( isDrag ) return ; Vector3 v3 &#61; transform . localPosition ; float value &#61; 0 ; if ( isHorizontal ) { value &#61; nowLocation - v3 . x ; if ( Mathf . Abs ( value ) < EffortsFlip ) return ; if ( value > 0 ) { if ( mPageIndex < pageNums ) Page (- pageWidth ); } else { if ( mPageIndex > 1 ) Page ( pageWidth ); } } else { value &#61; nowLocation - v3 . y ; if ( Mathf . Abs ( value ) < EffortsFlip ) return ; if ( value > 0 ) { if ( mPageIndex > 1 ) Page (- pageWidth ); } else { if ( mPageIndex < pageNums ) Page ( pageWidth ); } } } void Page ( float value ) { isSpringMove &#61; true ; isDrag &#61; true ; mSp &#61; GetComponent (); if ( mSp &#61;&#61; null ) mSp &#61; gameObject . AddComponent (); //mSp.enabled &#61; false; Vector3 pos &#61; mSp . target ; pos &#61; isHorizontal ? new Vector3 ( pos . x &#43; value , pos . y , pos . z ) : new Vector3 ( pos . x , pos . y &#43; value , pos . z ); if (! SetIndexPage ( pos )) return ; SpringPanel . Begin ( gameObject , pos , 13f ). strength &#61; 8f ; mSp . onFinished &#61; SpringPanleMoveEnd ; Debug . Log ( "page index&#61;" &#43; mPageIndex ); } void SpringPanleMoveEnd () { isSpringMove &#61; false ; } void onStoppedMoving () { isDrag &#61; false ; SetNowLocation (); } void SetNowLocation () { if ( isHorizontal ) { nowLocation &#61; gameObject . transform . localPosition . x ; } else { nowLocation &#61; gameObject . transform . localPosition . y ; } } bool SetIndexPage ( Vector3 v3 ) { float value &#61; isHorizontal ? v3 . x : v3 . y ; //Debug.Log((pageNums - 1) * pageWidth); if ( isHorizontal ) { if ( value > 0 || value < ( pageNums - 1 ) * - pageWidth ) return false ; } else { if ( value < 0 || value > ( pageNums - 1 ) * pageWidth ) return false ; } value &#61; Mathf . Abs ( value ); mPageIndex &#61; ( int )( value / pageWidth ) &#43; 1 ; return true ; } #region 公共接口 游*客*学*院 /// /// 上一页 /// public void PreviousPage () { if ( isHorizontal ) { if ( mPageIndex > 1 ) Page ( pageWidth ); } else { if ( mPageIndex < pageNums ) Page ( pageWidth ); } } /// /// 下一页 /// public void NextPage () { if ( isHorizontal ) { if ( mPageIndex < pageNums ) Page (- pageWidth ); } else { if ( mPageIndex > 1 ) Page (- pageWidth ); } } #endregion }
//UGUI..............................................\
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.UI; public class GridItem { public string cnName; public string usName; public GridItem(string cnN,string usN) { cnName &#61; cnN; usName &#61; usN; } } public class PaginationPanel : MonoBehaviour { /// /// 当前页面索引 /// public int m_PageIndex &#61; 1; /// /// 总页数 /// public int m_PageCount &#61; 0; /// /// 每页元素数 /// public int m_PerPageCount &#61; 0; /// /// 元素总个数 /// public int m_ItemsCount &#61; 0; /// /// 元素列表 /// public List m_ItemsList; /// /// 上一页 /// public Button m_BtnPrevious; /// /// 下一页 /// public Button m_BtnNext; /// /// 显示当前页数的标签 /// public Text m_PanelText; public Transform m_FrontPanel; public Transform m_BackPanel; public bool m_IsTouching; [Range(-1,1)] public float m_TouchDelta; public float m_MoveSpeed &#61; 5f; public float m_FadeDistance; public Vector3 m_PrePos; public Vector3 m_CenterPos; public Vector3 m_NextPos; public bool m_DoPrevious; public bool m_DoNext; public float m_CurrAlpha; private bool m_HasPrevious; private bool m_HasNext; private bool m_IsSaveBeforeTouch; public int m_FrontPanelPageIndex; private bool m_CanChangePage; private bool m_IsBackPageIndex; void Start() { InitGUI(); InitItems(); } /// /// 初始化GUI /// private void InitGUI() { //m_BtnNext &#61; GameObject.Find("Canvas/Panel/BtnNext").GetComponent(); //m_BtnPrevious &#61; GameObject.Find("Canvas/Panel/BtnPrevious").GetComponent(); //m_PanelText &#61; GameObject.Find("Canvas/Panel/Text").GetComponent(); //为上一页和下一页添加事件 m_BtnNext.onClick.AddListener(() &#61;> { OnNextBtnClick(); }); m_BtnPrevious.onClick.AddListener(() &#61;> { OnPreviousBtnClick(); }); m_PerPageCount &#61; m_FrontPanel.childCount; m_FadeDistance &#61; Mathf.Abs(m_FrontPanel.localPosition.y - m_BackPanel.localPosition.y); m_PrePos &#61; m_FrontPanel.localPosition; m_PrePos.y &#43;&#61; m_FadeDistance; m_NextPos &#61; m_FrontPanel.localPosition; m_NextPos.y -&#61; m_FadeDistance; m_CenterPos &#61; m_FrontPanel.localPosition; m_CanChangePage &#61; true; m_FrontPanelPageIndex &#61; 1; } /// /// 初始化元素 /// private void InitItems() { //准备一个存储着12生肖信息的数组 GridItem[] items &#61; new GridItem[] { new GridItem("鼠","Mouse"), new GridItem("牛","Ox"), new GridItem("虎","Tiger"), new GridItem("兔","Rabbit"), new GridItem("龙","Dragon"), new GridItem("蛇","Snake"), new GridItem("马","Horse"), new GridItem("羊","Goat"), new GridItem("猴","Monkey"), new GridItem("鸡","Rooster"), new GridItem("狗","Dog"), new GridItem("猪","Pig") }; //利用12生肖数组来随机生成列表 m_ItemsList &#61; new List(); for (int i &#61; 0; i { m_ItemsList.Add(items[i]); } //计算元素总个数 m_ItemsCount &#61; m_ItemsList.Count; //计算总页数 m_PageCount &#61; (m_ItemsCount % m_PerPageCount) &#61;&#61; 0 ? m_ItemsCount / m_PerPageCount : (m_ItemsCount / m_PerPageCount) &#43; 1; BindPage(m_FrontPanel, m_PageIndex); //更新界面页数 m_PanelText.text &#61; string.Format("{0}/{1}", m_PageIndex.ToString(), m_PageCount.ToString()); } private void Update() { if (m_IsTouching) { if (!m_IsSaveBeforeTouch) { m_IsSaveBeforeTouch &#61; true; m_FrontPanelPageIndex &#61; m_PageIndex; } if (m_TouchDelta > 0) { if (!m_HasPrevious && m_FrontPanelPageIndex > 1) { m_HasNext &#61; false; m_HasPrevious &#61; true; TouchPrevious(); } if (m_DoPrevious) { m_IsBackPageIndex &#61; false; m_BackPanel.localPosition &#61; Vector3.Lerp(m_PrePos, m_CenterPos, Mathf.Abs(m_TouchDelta)); m_BackPanel.GetComponent().alpha &#61; Mathf.Abs(m_TouchDelta); } m_FrontPanel.localPosition &#61; Vector3.Lerp(m_CenterPos, m_NextPos, Mathf.Abs(m_TouchDelta)); m_FrontPanel.GetComponent().alpha &#61; 1 - Mathf.Abs(m_TouchDelta); } else if (m_TouchDelta <0) { if (!m_HasNext && m_FrontPanelPageIndex { m_HasNext &#61; true; m_HasPrevious &#61; false; TouchNext(); } if (m_DoNext) { m_IsBackPageIndex &#61; false; m_BackPanel.localPosition &#61; Vector3.Lerp(m_NextPos, m_CenterPos, Mathf.Abs(m_TouchDelta)); m_BackPanel.GetComponent().alpha &#61; Mathf.Abs(m_TouchDelta); } m_FrontPanel.localPosition &#61; Vector3.Lerp(m_CenterPos, m_PrePos, Mathf.Abs(m_TouchDelta)); m_FrontPanel.GetComponent().alpha &#61; 1 - Mathf.Abs(m_TouchDelta); } } else { m_HasNext &#61; false; m_HasPrevious &#61; false; m_IsSaveBeforeTouch &#61; false; float a &#61; Mathf.Abs(m_FrontPanel.localPosition.y - m_CenterPos.y) / m_FadeDistance; m_CurrAlpha &#61; a; if (m_TouchDelta >&#61; 0.5f) { //float a &#61; Mathf.Abs(m_FrontPanel.localPosition.y - m_CenterPos.y) / m_FadeDistance; if (m_DoPrevious) { m_BackPanel.localPosition &#61; Vector3.Lerp(m_BackPanel.localPosition, m_CenterPos, m_MoveSpeed * Time.deltaTime); m_BackPanel.GetComponent().alpha &#61; a; m_FrontPanel.localPosition &#61; Vector3.Lerp(m_FrontPanel.localPosition, m_NextPos, m_MoveSpeed * Time.deltaTime); m_FrontPanel.GetComponent().alpha &#61; 1 - a; if (1 - a <0.01f) { m_TouchDelta &#61; 0; SwitchPanel(); } } else { m_TouchDelta &#61; 0; } } else if (m_TouchDelta <&#61; -0.5f) { //float a &#61; Mathf.Abs(m_FrontPanel.localPosition.y - m_CenterPos.y) / m_FadeDistance; if (m_DoNext) { m_BackPanel.localPosition &#61; Vector3.Lerp(m_BackPanel.localPosition, m_CenterPos, m_MoveSpeed * Time.deltaTime); m_BackPanel.GetComponent().alpha &#61; a; m_FrontPanel.localPosition &#61; Vector3.Lerp(m_FrontPanel.localPosition, m_PrePos, m_MoveSpeed * Time.deltaTime); m_FrontPanel.GetComponent().alpha &#61; 1 - a; if (1 - a <0.01f) { m_TouchDelta &#61; 0; SwitchPanel(); } } else { m_TouchDelta &#61; 0; } } else { //float a &#61; Mathf.Abs(m_FrontPanel.localPosition.y - m_CenterPos.y) / m_FadeDistance; if (m_DoPrevious) { if (!m_IsBackPageIndex) { m_IsBackPageIndex &#61; true; m_PageIndex &#61; m_FrontPanelPageIndex; } if (m_PageIndex 1) { m_BackPanel.localPosition &#61; Vector3.Lerp(m_BackPanel.localPosition, m_PrePos, m_MoveSpeed * Time.deltaTime); m_BackPanel.GetComponent().alpha &#61; a; } } else if (m_DoNext) { if (!m_IsBackPageIndex) { m_IsBackPageIndex &#61; true; m_PageIndex &#61; m_FrontPanelPageIndex; } if (m_PageIndex 1) { m_BackPanel.localPosition &#61; Vector3.Lerp(m_BackPanel.localPosition, m_NextPos, m_MoveSpeed * Time.deltaTime); m_BackPanel.GetComponent().alpha &#61; a; } } m_FrontPanel.localPosition &#61; Vector3.Lerp(m_FrontPanel.localPosition,m_CenterPos, m_MoveSpeed * Time.deltaTime); m_FrontPanel.GetComponent().alpha &#61; 1 - a; if (m_TouchDelta !&#61; 0 && a <0.01f) { m_TouchDelta &#61; 0; m_DoNext &#61; false; m_DoPrevious &#61; false; m_CanChangePage &#61; true; } } } } private void SwitchPanel() { m_DoPrevious &#61; false; m_DoNext &#61; false; Transform temp &#61; m_FrontPanel; m_FrontPanel &#61; m_BackPanel; m_BackPanel &#61; temp; m_CanChangePage &#61; true; } public void OnNextBtnClick() { if (!m_CanChangePage) return; m_TouchDelta &#61; -0.6f; Next(); } /// /// 下一页 /// public void Next() { if (m_PageCount <&#61; 0) return; //最后一页禁止向后翻页 if (m_PageIndex >&#61; m_PageCount) return; m_CanChangePage &#61; false; m_PageIndex &#43;&#61; 1; if (m_PageIndex >&#61; m_PageCount) m_PageIndex &#61; m_PageCount; m_BackPanel.localPosition &#61; m_NextPos; BindPage(m_BackPanel, m_PageIndex); m_DoNext &#61; true; m_DoPrevious &#61; false; //更新界面页数 m_PanelText.text &#61; string.Format("{0}/{1}", m_PageIndex.ToString(), m_PageCount.ToString()); } /// /// 下一页 /// public void TouchNext() { if (m_PageCount <&#61; 0) return; //最后一页禁止向后翻页 if (m_FrontPanelPageIndex >&#61; m_PageCount) return; m_CanChangePage &#61; false; m_PageIndex &#61; m_FrontPanelPageIndex &#43; 1; if (m_PageIndex >&#61; m_PageCount) m_PageIndex &#61; m_PageCount; m_BackPanel.localPosition &#61; m_NextPos; BindPage(m_BackPanel, m_PageIndex); m_DoNext &#61; true; m_DoPrevious &#61; false; //更新界面页数 m_PanelText.text &#61; string.Format("{0}/{1}", m_PageIndex.ToString(), m_PageCount.ToString()); } public void OnPreviousBtnClick() { if (!m_CanChangePage) return; m_TouchDelta &#61; 0.6f; Previous(); } /// /// 上一页 /// public void Previous() { if (m_PageCount <&#61; 0) return; //第一页时禁止向前翻页 if (m_PageIndex <&#61; 1) return; m_CanChangePage &#61; false; m_PageIndex -&#61; 1; if (m_PageIndex <1) m_PageIndex &#61; 1; m_BackPanel.localPosition &#61; m_PrePos; BindPage(m_BackPanel, m_PageIndex); m_DoPrevious &#61; true; m_DoNext &#61; false; //更新界面页数 m_PanelText.text &#61; string.Format("{0}/{1}", m_PageIndex.ToString(), m_PageCount.ToString()); } /// /// 上一页 /// public void TouchPrevious() { if (m_PageCount <&#61; 0) return; //第一页时禁止向前翻页 if (m_FrontPanelPageIndex <&#61; 1) return; m_CanChangePage &#61; false; m_PageIndex &#61; m_FrontPanelPageIndex -1; if (m_PageIndex <1) m_PageIndex &#61; 1; m_BackPanel.localPosition &#61; m_PrePos; BindPage(m_BackPanel, m_PageIndex); m_DoPrevious &#61; true; m_DoNext &#61; false; //更新界面页数 m_PanelText.text &#61; string.Format("{0}/{1}", m_PageIndex.ToString(), m_PageCount.ToString()); } /// /// 绑定指定索引处的页面元素 /// /// 页面索引 private void BindPage(Transform tran,int index) { //列表处理 if (m_ItemsList &#61;&#61; null || m_ItemsCount <&#61; 0) return; //索引处理 if (index <0 || index > m_ItemsCount) return; //按照元素个数可以分为1页和1页以上两种情况 if (m_PageCount &#61;&#61; 1) { int canDisplay &#61; 0; for (int i &#61; m_PerPageCount; i > 0; i--) { if (canDisplay { BindGridItem(tran.GetChild(canDisplay), m_ItemsList[m_PerPageCount - i]); tran.GetChild(canDisplay).gameObject.SetActive(true); } else { //对超过canDispaly的物体实施隐藏 tran.GetChild(canDisplay).gameObject.SetActive(false); } canDisplay &#43;&#61; 1; } } else if (m_PageCount > 1) { //1页以上需要特别处理的是最后1页 //和1页时的情况类似判断最后一页剩下的元素数目 //第1页时显然剩下的为12所以不用处理 if (index &#61;&#61; m_PageCount) { int canDisplay &#61; 0; for (int i &#61; m_PerPageCount; i > 0; i--) { //最后一页剩下的元素数目为 m_ItemsCount - 12 * (index-1) if (canDisplay { BindGridItem(tran.GetChild(canDisplay), m_ItemsList[m_PerPageCount * index - i]); tran.GetChild(canDisplay).gameObject.SetActive(true); } else { //对超过canDispaly的物体实施隐藏 tran.GetChild(canDisplay).gameObject.SetActive(false); } canDisplay &#43;&#61; 1; } } else { for (int i &#61; m_PerPageCount; i > 0; i--) { BindGridItem(tran.GetChild(m_PerPageCount - i), m_ItemsList[m_PerPageCount * index - i]); tran.GetChild(m_PerPageCount - i).gameObject.SetActive(true); } } } } /// /// 加载一个Sprite /// /// 资源名称 private Sprite LoadSprite(string assetName) { Texture texture &#61; (Texture)Resources.Load(assetName); Sprite sprite &#61; Sprite.Create((Texture2D)texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)); return sprite; } /// /// 将一个GridItem实例绑定到指定的Transform上 /// /// /// private void BindGridItem(Transform trans, GridItem gridItem) { //trans.GetComponent().sprite &#61; LoadSprite(gridItem.ItemSprite); trans.GetComponent().text &#61; gridItem.cnName; } }