unity實現無限列表功能
阿新 • • 發佈:2020-04-17
本文例項為大家分享了unity實現無限列表功能的具體程式碼,供大家參考,具體內容如下
public static class RectTransformExtensions { public static bool Overlaps(this RectTransform a,RectTransform b) { return a.WorldRect().Overlaps(b.WorldRect()); } public static bool Overlaps(this RectTransform a,RectTransform b,bool allowInverse) { return a.WorldRect().Overlaps(b.WorldRect(),allowInverse); } public static Rect WorldRect(this RectTransform rectTransform) { Vector2 sizeDelta = rectTransform.sizeDelta; float rectTransformWidth = sizeDelta.x * rectTransform.lossyScale.x; float rectTransformHeight = sizeDelta.y * rectTransform.lossyScale.y; Vector3 position = rectTransform.position; return new Rect( position.x - rectTransformWidth * rectTransform.pivot.x,position.y - rectTransformHeight * rectTransform.pivot.y,rectTransformWidth,rectTransformHeight); } /// <summary> /// /// </summary> /// <param name="rectTransform"></param> /// <param name="pos">世界座標的position</param> /// <returns></returns> public static Rect WorldRect2(this RectTransform rectTransform,Vector3 pos) { Rect rect = new Rect(); Vector2 sizeDelta = rectTransform.sizeDelta; float rectTransformWidth = sizeDelta.x * rectTransform.lossyScale.x; float rectTransformHeight = sizeDelta.y * rectTransform.lossyScale.y; Vector3 position = pos; rect.x = position.x - rectTransformWidth * rectTransform.pivot.x; rect.y = position.y - rectTransformHeight * rectTransform.pivot.y; rect.width = rectTransformWidth; rect.height = rectTransformHeight; return rect; } }
以上拓展方法是判斷兩個Recttransform型別的物體是否相交。
然後ScrollRec的滑動回撥方法中更新UI位置,程式碼如下
private void OnScrollRectValueChanged(Vector2 arg0) { Dictionary<int,DynamicRect> inOverlaps = new Dictionary<int,DynamicRect>(); mRectMask = 遮罩物體的RectTransform.WorldRect(); //m_DynamicRectDic這個字典儲存的是你所有UI需要放置的位置資料, //判斷所有UI哪個是可見哪個不可見 ,儲存起來 foreach (DynamicRect dR in m_DynamicRectDic.Values) { tmpTra.localPosition = dR.localPos; //獲取每個位置UI的世界座標Rect Rect rect = m_LevelItemPrefabRT.WorldRect2(tmpTra.position); if (rect.Overlaps(mRectMask)) { inOverlaps.Add(dR.Index,dR); } } //m_LevelItemList是儲存你例項化後的UI列表,比如你這個遮罩頁面最多顯示3個UI,你需要例項化4個UI,然後動態修改gameobject的顯示與隱藏 int len = m_LevelItemList.Count; for (int i = 0; i < len; ++i) { //LevelItem是UI上掛載的指令碼,用於更新UI介面的顯示和資料儲存的 LevelItem item = m_LevelItemList[i]; if (item.DRect != null && !inOverlaps.ContainsKey(item.DRect.Index)) { //item的DRect為null時,隱藏物體,否則顯示物體 item.DRect = null; } } //判斷哪些可以重複利用的UI,然後賦予新的資料與位置 foreach (DynamicRect dR in inOverlaps.Values) { if (GetDynmicItem(dR) == null) { LevelItem item = GetNullDynmicItem(); if (item == null) continue; item.DRect = dR; //更新UI的位置和顯示(自己計算,每種顯示不一樣) _UpdateChildTransformPos(item.gameObject,dR.Index); } } } /// <summary> /// 通過動態格子獲得動態渲染器 /// </summary> /// <param name="rect"></param> /// <returns></returns> private LevelItem GetDynmicItem(DynamicRect rect) { int len = m_LevelItemList.Count; for (int i = 0; i < len; ++i) { LevelItem item = m_LevelItemList[i]; if (item.DRect == null) continue; if (rect.Index == item.DRect.Index) return item; } return null; } /// <summary> /// 獲得待渲染的渲染器 /// </summary> /// <returns></returns> private LevelItem GetNullDynmicItem() { int len = m_LevelItemList.Count; for (int i = 0; i < len; ++i) { LevelItem item = m_LevelItemList[i]; if (item.DRect == null) return item; } return null; } public class DynamicRect { /// <summary> /// 本地座標 /// </summary> public Vector3 localPos; /// <summary> /// 格子索引 /// </summary> public int Index; public DynamicRect(int index,Vector3 localPos) { this.Index = index; this.localPos = localPos; } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。