[Unity3D] UGUI ScrollRect效果大全

UGUI各種優(yōu)化效果

本文所實現(xiàn)的UGUI效果需求如下:?

-?支持縮放滑動效果?

-?支持動態(tài)縮放循環(huán)加載?

-?支持大數(shù)據(jù)固定Item復(fù)用加載?

-?支持不用Mask遮罩無限循環(huán)加載?

-?支持ObjectPool動態(tài)加載?

-?支持無限不規(guī)則子物體動態(tài)加載?

-?支持拖動并點擊和拖拽?

-?支持拖動并拖拽?

-?支持ScrollRect拖動自動吸附功能(拖動是否超過一半自動進退)

效果圖

縮放滑動效果?

縮放循環(huán)展示卡牌效果

大量數(shù)據(jù)無卡頓動態(tài)加載二汛,并且支持拖拽、點擊和吸附功能

大量數(shù)據(jù)循固定Item復(fù)用?

無限無遮罩動態(tài)加載

不規(guī)則子物體動態(tài)循環(huán)加載

部分核心代碼

有遮罩無卡頓加載?

思路:并沒有使用UGUI的ScrollRect組件忽舟,擺放幾張卡片任柜,通過移動和縮放來實現(xiàn)

usingUnityEngine;usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine.UI;publicclassEnhancelScrollView : MonoBehaviour{// 縮放曲線publicAnimationCurve scaleCurve;// 位移曲線publicAnimationCurve positionCurve;// 位移系數(shù)publicfloatposCurveFactor =500.0f;// y軸坐標(biāo)固定值(所有的item的y坐標(biāo)一致)publicfloatyPositionValue =46.0f;// 添加到EnhanceScrollView的目標(biāo)對象publicList



有遮罩無卡頓加載?

思路:協(xié)程加載何址,先加載屏幕顯示的數(shù)量民宿,然后返回一幀在繼續(xù)加載,防止出現(xiàn)數(shù)量太大卡頓的現(xiàn)象痴突。

while(CardsList.Count > roleInfo.Count){? ? DestroyImmediate(CardsList[0].gameObject);? ? CardsList.RemoveAt(0);}StartCoroutine(createRoleCards());privateIEnumeratorcreateRoleCards(){? ? List charInfos =newList();? ? charInfos.AddRange(roleInfo);intindex =0;for(inti =0; i < charInfos.Count; i++)? ? {? ? ? ? _createRoleCard(charInfos[i], index++);if(index %10==0)yieldreturnnull;? ? }}privatevoid_createRoleCard(CLocalCharInfo roleInfo,intindex){? ? CUIPlayedCharCardWidget charCardWidget =null;if(CardsList.Count > index)? ? {? ? ? ? charCardWidget = CardsList[index];? ? }else{varobj = Instantiate(Resources.Load("Prefab/RoleCard"))asGameObject;if(obj ==null)? ? ? ? {? ? ? ? ? ? UnityEngine.Debug.LogError("有誤");return;? ? ? ? }? ? ? ? obj.name = roleInfo.Name;? ? ? ? charCardWidget = obj.GetComponent();if(charCardWidget ==null)? ? ? ? {? ? ? ? ? ? UnityEngine.Debug.LogError("有誤");return;? ? ? ? }? ? ? ? obj.transform.parent = Obj_ScrollViewContent.transform;? ? ? ? obj.transform.localScale = Vector3.one;? ? ? ? CardsList.Add(charCardWidget);? ? }? ? CUIPlayedCharCardWidget.CUIContent uiContent =newCUIPlayedCharCardWidget.CUIContent();? ? uiContent.RoleInfo = roleInfo;? ? uiContent.ScrollRectObj = m_ScrollRect;? ? uiContent.FixGridRect = m_FixGrid;? ? charCardWidget.InitContent(uiContent);}


支持ScrollRect拖拽或點擊?

思路:在卡片的Image上添加一個繼承了IBeginDragHandler,IGradHandler,IEndDragHandler的腳本粉渠,重寫接口里面的Drag事件方法。

usingUnityEngine;usingUnityEngine.EventSystems;usingUnityEngine.UI;namespace Mga{? ? [RequireComponent(typeof(Image))]publicclassCPlayedCardOnDrag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler? ? {publicbooldragOnSurfaces =true;publicScrollRect m_ScrollRect =null;publicCFixGridRect m_FixGridRect =null;privateGameObject m_DraggingCard;privateRectTransform m_DraggingPlane;publicboolisVertical =false;privateboolisSelf =false;privateSystem.Action m_OnBeginDragCallBack =null;privateSystem.Action m_OnEndDragCallBack =null;privateSystem.Action m_OnBeginScroll =null;privateSystem.Action m_OnEndScroll =null;publicvoidInit(CLocalCharInfo roleInfo, System.Action beginCallBack =null, System.Action endCallBack =null, System.Action beginScroll =null, System.Action endScroll =null)? ? ? ? {? ? ? ? ? ? m_OnBeginDragCallBack = beginCallBack;? ? ? ? ? ? m_OnEndDragCallBack = endCallBack;? ? ? ? ? ? m_OnBeginScroll = beginScroll;? ? ? ? ? ? m_OnEndScroll = endScroll;? ? ? ? }publicvoidOnBeginDrag(PointerEventData eventData)? ? ? ? {? ? ? ? ? ? Vector2 touchDeltaPosition = Vector2.zero;#ifUNITY_EDITORfloatdelta_x = Input.GetAxis("Mouse X");floatdelta_y = Input.GetAxis("Mouse Y");? ? ? ? ? ? touchDeltaPosition =newVector2(delta_x, delta_y);#elifUNITY_ANDROID || UNITY_IPHONEtouchDeltaPosition = Input.GetTouch(0).deltaPosition;#endifif(isVertical)? ? ? ? ? ? {if(Mathf.Abs(touchDeltaPosition.x) > Mathf.Abs(touchDeltaPosition.y))? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? isSelf =true;varcanvas = FindInParents


如果想要實現(xiàn)拖拽到目標(biāo)位置的檢測派哲,還要在目標(biāo)位置放一個Image并且添加上繼承了IDropHandler,IPointerEnterHandler,IPointerExitHanler的組件。



在ScrollRect物體上添加吸附功能組件掺喻,工程里面要使用DoTween插件

usingSystem.Collections.Generic;usingDG.Tweening;usingUnityEngine;usingUnityEngine.EventSystems;usingUnityEngine.UI;//TODO:當(dāng)前只試應(yīng)橫向的ScrollRect芭届,還需要擴展支持縱向publicclassCFixGridRect : MonoBehaviour, IEndDragHandler{publicGameObject content;publicScrollRect scorllRect;publicfloatitemWidth;privateRectTransform contentRectTf;privatefloatformalPosX =0;privatefloatcurrentPosX =0;privatefloathalfItemLength =0;voidStart()? ? {if(itemWidth <=0)? ? ? ? ? ? UnityEngine.Debug.LogError("請設(shè)置Item的寬度");? ? ? ? halfItemLength = itemWidth /2;this.contentRectTf =this.content.GetComponent();? ? }publicvoidOnEndDrag(PointerEventData eventData)? ? {this.scorllRect.StopMovement();? ? ? ? Vector2 afterDragPagePos =this.content.transform.localPosition;? ? ? ? currentPosX = afterDragPagePos.x;//當(dāng)前拖動的位置? 負if(scorllRect.horizontalNormalizedPosition <0|| scorllRect.horizontalNormalizedPosition >1)return;intcount = (int)(Mathf.Abs(currentPosX) / itemWidth);vartargetPos = -(float)(count * itemWidth);if(((float)(count * itemWidth + halfItemLength)) < Mathf.Abs(currentPosX))? ? ? ? {? ? ? ? ? ? targetPos = -(float)((count +1) * itemWidth);? ? ? ? }? ? ? ? formalPosX = targetPos;this.contentRectTf.DOLocalMoveX(targetPos,.2f);? ? }}



優(yōu)化支持橫豎屏的ScrollRect吸附功能

usingSystem.Collections.Generic;usingDG.Tweening;usingUnityEngine;usingUnityEngine.EventSystems;usingUnityEngine.UI;namespace Mga{publicenumDragDirection? ? {? ? ? ? Horizontal,? ? ? ? Vertical,? ? }publicclassCFixGridRectBase : MonoBehaviour, IEndDragHandler? ? {publicclassCUIContent? ? ? ? {publicGameObject ScrollRectContent;publicScrollRect m_ScorllRect;publicfloatItemSize;publicfloatItemSpaceLength;//間隙publicfloatMargin =0;//頂部邊緣間隙publicDragDirection m_DragDirection = DragDirection.Vertical;? ? ? ? }privateRectTransform contentRectTf;privatefloathalfItemLength =0;privateCUIContent m_uiContent =null;privateboolm_bWidgetReady =false;voidStart()? ? ? ? {? ? ? ? ? ? m_bWidgetReady =true;? ? ? ? ? ? _initContent();? ? ? ? }publicvoidInitContent(CUIContent uiContent)? ? ? ? {? ? ? ? ? ? m_uiContent = uiContent;if(m_bWidgetReady)? ? ? ? ? ? ? ? _initContent();? ? ? ? }privatevoid_initContent()? ? ? ? {if(m_uiContent ==null)return;if(m_uiContent.ItemSize <=0)? ? ? ? ? ? {? ? ? ? ? ? ? ? UnityEngine.Debug.LogError("請設(shè)置Item的寬度");return;? ? ? ? ? ? }? ? ? ? ? ? halfItemLength = m_uiContent.ItemSize /2;this.contentRectTf = m_uiContent.ScrollRectContent.GetComponent();? ? ? ? }publicvoidOnEndDrag(PointerEventData eventData)? ? ? ? {? ? ? ? ? ? m_uiContent.m_ScorllRect.StopMovement();? ? ? ? ? ? Vector2 afterDragPagePos = m_uiContent.ScrollRectContent.transform.localPosition;varitemLength = m_uiContent.ItemSize + m_uiContent.ItemSpaceLength;if(m_uiContent.m_DragDirection == DragDirection.Horizontal)? ? ? ? ? ? {varcurrentPosX = afterDragPagePos.x;//當(dāng)前拖動的位置? 負currentPosX -= m_uiContent.Margin;intcount = (int)(Mathf.Abs(currentPosX) / m_uiContent.ItemSize);if(m_uiContent.m_ScorllRect.horizontalNormalizedPosition <=0)? ? ? ? ? ? ? ? {return;? ? ? ? ? ? ? ? }elseif(m_uiContent.m_ScorllRect.horizontalNormalizedPosition >=1)//總數(shù)-當(dāng)前顯示的數(shù)量{return;? ? ? ? ? ? ? ? }vartargetPosX = -(float)(count * itemLength);if(((float)(targetPosX + halfItemLength)) < Mathf.Abs(currentPosX))? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? count++;? ? ? ? ? ? ? ? ? ? targetPosX = -(float)(count * itemLength);? ? ? ? ? ? ? ? }this.contentRectTf.DOLocalMoveX(targetPosX,.2f);? ? ? ? ? ? }else{varcurrentPosY = afterDragPagePos.y;//當(dāng)前拖動的位置? 正currentPosY -= m_uiContent.Margin;intcount = (int)(Mathf.Abs(currentPosY) / itemLength);if(m_uiContent.m_ScorllRect.verticalNormalizedPosition <=0)? ? ? ? ? ? ? ? {return;? ? ? ? ? ? ? ? }elseif(m_uiContent.m_ScorllRect.verticalNormalizedPosition >=1)//總數(shù)-當(dāng)前顯示的數(shù)量{return;? ? ? ? ? ? ? ? }vartargetPosY = (float)(count * itemLength);if(((float)(targetPosY + halfItemLength)) < Mathf.Abs(currentPosY))? ? ? ? ? ? ? ? {? ? ? ? ? ? ? ? ? ? count++;? ? ? ? ? ? ? ? ? ? targetPosY = (float)(count * itemLength);? ? ? ? ? ? ? ? }this.contentRectTf.DOLocalMoveY(targetPosY,.2f);? ? ? ? ? ? }? ? ? ? }? ? }}


補充

如果代碼創(chuàng)建AnimationCurve默認是曲線,如果想要直線效果感耙,可以在面板里面設(shè)置褂乍,也可以代碼設(shè)置,如果代碼設(shè)置如下:

var curve2 = new AnimationCurve();var key1 = new Keyframe(0,0);key1.outTangent=1;var key2 = new Keyframe(1,1);key2.inTangent=1;curve2.AddKey(key1);curve2.AddKey(key2);curve2.postWrapMode= WrapMode.Loop;curve2.preWrapMode= WrapMode.Loop;


這樣的話就是直線了即硼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逃片,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子只酥,更是在濱河造成了極大的恐慌褥实,老刑警劉巖呀狼,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異损离,居然都是意外死亡哥艇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門僻澎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來她奥,“玉大人,你說我怎么就攤上這事怎棱×螅” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵拳恋,是天一觀的道長凡资。 經(jīng)常有香客問我,道長谬运,這世上最難降的妖魔是什么隙赁? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮梆暖,結(jié)果婚禮上伞访,老公的妹妹穿的比我還像新娘。我一直安慰自己轰驳,他們只是感情好厚掷,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著级解,像睡著了一般冒黑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勤哗,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天抡爹,我揣著相機與錄音,去河邊找鬼芒划。 笑死冬竟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的民逼。 我是一名探鬼主播泵殴,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼缴挖!你這毒婦竟也來了袋狞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤映屋,失蹤者是張志新(化名)和其女友劉穎苟鸯,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棚点,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡早处,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瘫析。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砌梆。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贬循,靈堂內(nèi)的尸體忽然破棺而出咸包,到底是詐尸還是另有隱情,我是刑警寧澤杖虾,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布烂瘫,位于F島的核電站,受9級特大地震影響奇适,放射性物質(zhì)發(fā)生泄漏坟比。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一嚷往、第九天 我趴在偏房一處隱蔽的房頂上張望葛账。 院中可真熱鬧,春花似錦皮仁、人聲如沸籍琳。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽巩割。三九已至,卻和暖如春付燥,著一層夾襖步出監(jiān)牢的瞬間宣谈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工键科, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闻丑,地道東北人。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓勋颖,卻偏偏與公主長得像嗦嗡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子饭玲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1.HashMap是一個數(shù)組+鏈表/紅黑樹的結(jié)構(gòu)侥祭,數(shù)組的下標(biāo)在HashMap中稱為Bucket值,每個數(shù)組項對應(yīng)的...
    誰在烽煙彼岸閱讀 1,014評論 2 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法矮冬,內(nèi)部類的語法谈宛,繼承相關(guān)的語法,異常的語法胎署,線程的語...
    子非魚_t_閱讀 31,587評論 18 399
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,028評論 0 2
  • Adding Multiplayer shooting 添加多人射擊 This section adds netw...
    慕城祉宇流年殤閱讀 713評論 0 0
  • 2017.5.24 一吆录、本期目標(biāo) 實現(xiàn)財富收入50萬元(8月底前) 二、具體播種 1.晨起在微信對師兄發(fā)出群收款琼牧,...
    鵲曾閱讀 193評論 0 2