Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果_第1頁(yè)
Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果_第2頁(yè)
Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果_第3頁(yè)
Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果_第4頁(yè)
Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果_第5頁(yè)
已閱讀5頁(yè),還剩2頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第UnityScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果本文實(shí)例為大家分享了UnityScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果的具體代碼,供大家參考,具體內(nèi)容如下

以下內(nèi)容是根據(jù)Unity2025.1.01f版本進(jìn)行編寫的

工作中遇到有需要實(shí)現(xiàn)軌跡滑動(dòng)的滑動(dòng)列表,通常的做法是計(jì)算貝塞爾曲線得出軌跡,但是我覺得計(jì)算貝塞爾曲線太麻煩了,或許有沒有更簡(jiǎn)單的方法。

軌跡滑動(dòng)可以分兩種情況:

第一種是軌跡滑動(dòng)是比較簡(jiǎn)單的橫向(或縱向)滑動(dòng),其中軌跡不會(huì)蜿蜒盤旋,也不涉及列表格子之間的重疊關(guān)系,這時(shí)可以分區(qū)間來(lái)對(duì)Y軸(或X軸)進(jìn)行設(shè)置以達(dá)到格子沿著軌跡滑動(dòng)的效果

例如,軌跡是這樣的波浪型的,其中,軌跡點(diǎn)的數(shù)量可以無(wú)限增加,點(diǎn)越多軌跡可以設(shè)置得越平滑,但是消耗的性能也越多:

像這樣,類似波浪型的軌跡,可以用一個(gè)Vector列表記錄下每個(gè)點(diǎn)的位置和順序,然后根據(jù)每個(gè)格子所在的位置,先由小到大循環(huán)判斷在哪個(gè)區(qū)間,例如格子3在pos_5和pos_6中間,所以第三個(gè)格子的區(qū)間就是5,然后通過(guò)pos_5和pos_6兩個(gè)點(diǎn)相減,得到一個(gè)從pos_5指向pos_6的向量vector,通過(guò)vector3.distance函數(shù)得到pos_5和pos_6兩個(gè)點(diǎn)的橫向距離distanceX1,然后再次通過(guò)vector3.distance函數(shù)得到pos_5與格子3得橫向距離distanceX2,那么,格子3的位置=pos_5的位置+distanceX2/distanceX1*vector,得到位置后再把位置設(shè)置回去就可以了

第二種就是更為復(fù)雜的軌跡滑動(dòng),例如蜿蜒盤旋式的軌跡,其中還包括有層級(jí)關(guān)系

例如,軌跡是蜿蜒盤旋的,同樣是軌跡點(diǎn)越多,曲線越平滑,也越消耗性能:

像這樣,蜿蜒盤旋的軌跡,就不能使用第一種方法了,因?yàn)橛行┪恢?,一個(gè)X值對(duì)應(yīng)下來(lái)有多個(gè)Y值,無(wú)法區(qū)分當(dāng)前需要的是哪個(gè)Y值,所以,需要使用另一種方法

我們可以通過(guò)獲取所有的軌跡點(diǎn),計(jì)算出每?jī)蓚€(gè)相鄰軌跡點(diǎn)之間的距離,通過(guò)距離確定格子應(yīng)該在哪個(gè)區(qū)間內(nèi)

例如,格子3的位置是95,假設(shè)pos_1和pos_2的距離為50,pos_2和pos_3的距離為也是50,那么pos_1到pos_3的總距離就是100,所以格子3應(yīng)該在區(qū)間pos_2和pos_3中間。接下來(lái)計(jì)算實(shí)際位置,因?yàn)榇藭r(shí)格子的X軸和Y軸都會(huì)變化,同樣無(wú)法使用第一種方法來(lái)計(jì)算格子的位置,需要通過(guò)格子的位置減去前面區(qū)間距離的和,在例子中,就是格子3的位置減去pos_1到pos_2的距離,即95–50=45,再通過(guò)剩余的距離除以當(dāng)前區(qū)間的距離得出比例ratio,然后就是通過(guò)當(dāng)前的兩個(gè)區(qū)間點(diǎn)相減得到pos_2指向pos_3的向量vector,那么格子3的位置就是,pos_2的位置+ratio*vector

最后,還有層級(jí)的問(wèn)題,也就是哪個(gè)格子遮擋哪個(gè)格子,一般是后面的格子遮擋前面的格子,如果需要前面的遮擋后面的格子,只需要?jiǎng)討B(tài)修改層級(jí)就行,unity提供了這個(gè)函數(shù):Transform.SetAsFirstSibling()

在實(shí)際使用中,我發(fā)現(xiàn)使用這種方法后,content的長(zhǎng)度有時(shí)候會(huì)過(guò)長(zhǎng),有時(shí)候會(huì)過(guò)短,所以需要確定好格子的數(shù)量,設(shè)置好content的正確長(zhǎng)度

注意:以上都是最基礎(chǔ)的思想,因?yàn)榛瑒?dòng)時(shí)改變的是content節(jié)點(diǎn),格子的位置實(shí)際上是不變的,或者是由代碼設(shè)置的,所以實(shí)際代碼中還需要考慮scrollrect的寬高以及content節(jié)點(diǎn)的滑動(dòng)值(即posX值,滑動(dòng)時(shí)此值會(huì)變化)

3、自定義實(shí)現(xiàn)軌跡滑動(dòng)

usingSystem.Collections.Generic;

usingUnityEngine;

usingUnityEngine.UI;

[RequireComponent(typeof(ScrollRect))]

publicclassCurveSliding:MonoBehaviour

publicTransformposListRoot;

publicfloatcontentwidth;//必須自己設(shè)置的content實(shí)際長(zhǎng)度

publicboolisChangeHierarchy=false;

privateScrollRectscrollRect;

privateRectTransformcontent;

privateListTransformposTransformList=newListTransform

privateListRectTransformitem_transformList=newListRectTransform

privateListfloatposX_List=newListfloat

privateListfloatdistanceList=newListfloat

privatefloatscrollRectWidth;

privatefloatscrollRectHeight;

privatefloatposTotalDistance;

privatefloatspacing=0;

privatevoidStart()

scrollRect=GetComponentScrollRect

content=scrollRect.content.transformasRectTransform;

HorizontalLayoutGroupcontentLayoutGroup=content.GetComponentsInChildrenHorizontalLayoutGroup(true)[0];

if(contentLayoutGroup!=nullcontentLayoutG==)

spacing=contentLayoutGroup.spacing;

scrollRectWidth=scrollRect.GetComponentRectTransform().sizeDelta.x;

scrollRectHeight=scrollRect.GetComponentRectTransform().sizeDelta.y;

for(inti=0;icontent.childCount;i++)

RectTransformitem_transform=content.GetChild(i)asRectTransform;

if(item_transform.gameObject.activeInHierarchy)

item_transformList.Add(item_transform);

posX_List.Add(item_transform.localPosition.x);

else

continue;

floattotalDistance=0;

for(inti=0;iposListRoot.childCount;i++)

TransformposTransform=posListRoot.GetChild(i);

if(i0)

TransformpreviousPosTransform=posListRoot.GetChild(i-1);

totalDistance+=Vector3.Distance(posTransform.localPosition,previousPosTransform.localPosition);

posTransformList.Add(posTransform);

distanceList.Add(totalDistance);

posTotalDistance=distanceList[distanceList.Count-1];

content.sizeDelta=newVector2(contentwidth,content.sizeDelta.y);

OnValueChange(Vector2.zero);

scrollRect.onValueChanged.AddListener(OnValueChange);

publicvoidOnValueChange(Vector2vector)

for(inti=0;iitem_transformList.Count;i++)

floatlocalPosX=posX_List[i];

floatposX=localPosX+content.anchoredPosition.x;

//如果當(dāng)前節(jié)點(diǎn)的位置-content的X軸偏移值滑動(dòng)列表的寬度,則說(shuō)明當(dāng)前item在可視范圍外

if(posXposTotalDistance+200||posX0)

continue;

intindex=-1;

foreach(vartotalDistanceindistanceList)

if(posXtotalDistance)

break;

else

index++;

//如果index+1小于位置列表的數(shù)量,則其在位置區(qū)間內(nèi),否則應(yīng)該在位置區(qū)間外

if(index+1posListRoot.childCountindex+10)

floatratio=(posX-distanceList[index])/(distanceList[index+1]-distanceList[index]);

Vector3newPos=posTransformList[index].localPosition-ratio*(posTransformList[index].localPosition-posTransformList[index+1].localPosition);

item_transformList[i].localPosition=newVector3(newPos.x+scrollRectWidth/2-content.anchoredPosition.x,-scrollRectHeight/2+newPos.y,0);

elseif(index=-1)

item_transformList[i].localPosition=newVector3(item_transformList[i].localPosition.x,-scrollRectHeight/2+posListRoot.GetChild(0).localPosition.y,0);

elseif(index=posListRoot.childCount-1)

if(i1)

continue;

RectTransformpreviousItem_RectTransform=item_transformList[i-1];

item_transformList[i].localPosition=newVector3(previousItem_RectTransform.localPosition.x+spacing+previousItem_RectTransform.sizeDelta.x/2+item_transformList[i].sizeDelta.x/2,-scrollRectHeight/2+posListRoot.GetChild(posListRoot.childCount-1).localPosition.y,0);

if(isChangeHierarchy)

i

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論