Unity3D問題之EnhanceScollView選擇角色3D迴圈滾動效果實現,unity3dscrollview

來源:互聯網
上載者:User

Unity3D問題之EnhanceScollView選擇角色3D迴圈滾動效果實現,unity3dscrollview

需求

  • 呈現3D效果(2D素材)選擇角色效果
  • 滾動保證層級,縮放比例,間距正常跟隨
  • 迴圈滾動
  • 這個介面需求一般也會有遊戲會採用(貌似有挺多)
如何?

實現技術關鍵點

  1. 如何控制每個Item之間的間隔(位置),縮放比例,差值平滑
  2. 如何?item層級關係正確顯示("離" 螢幕近的層級高)
  3. 如何?迴圈滾動

下面一一講述當前Demo採用的方法
說到實現的核心,需要知道Unity3D中提供的一個叫做AnimationCurve的組件,這個不僅僅是表面上美術可以使用的組件,也不只是單純的動畫曲線的概念,當然它就是動畫曲線,但是我們可以賦予AnimationCurve不同的意義,則可以藉助Curve實現不同的功能,(AnimationCurve定義了一個變化趨勢或者曲線,在不同的時間點,我們可以得到目前時間點下該曲線對應的y軸資訊,這個資訊可以是角色跳躍的高度,模型縮放的一個係數,攝像機距離目標的長度,一個角色當前的心情數值等等,曲線可以表示很多的意義)
沒用過AnimationCurve的朋友,直接去官網看下介紹就明白如何使用
下面簡單說下使用AnimationCurve可以完成的一些功能(上面已經介紹了一部分情境)

  1. 角色2D跳躍
  2. 攝像機移動
  3. 角色心情指數
  4. 縮放係數
  5. 距離係數
  6. ......

我們也賦予AnimationCurve不同的意義,實現我們核心目標(控制位移,控制縮放 當然也可以控制層級)

控制位移,縮放(3D效果的關鍵),差值過度動畫平滑
  1. 建立兩個AnimationCurve一個是scaleAnimationCurve和positionXAnimationCurve,分別控制縮放和位移
  2. 時間流水線控制(我們把所有的Item設定好自己對應的時間流位置即可,每次只要一動時間流水線,然後從兩個曲線內獲得當前流水線對應的縮放係數,位移係數,然後設定item的位移和縮放即可)
  3. 如何製作動畫(這個其實就是簡單的時間流水線的差值處理,一定時間時間流水值達到目標值即可)
下面放上兩張曲線和具體實現:


/// <summary>    /// 縮放曲線類比當前縮放值    /// </summary>    private float GetScaleValue(float sliderValue, float added)    {        float scaleValue = scaleCurve.Evaluate(sliderValue + added);        return scaleValue;    }    /// <summary>    /// 位置曲線類比當前x軸位置    /// </summary>    private float GetXPosValue(float sliderValue, float added)    {        float evaluateValue = positionCurve.Evaluate(sliderValue + added) * posCurveFactor;        return evaluateValue;    }public void UpdateEnhanceScrollView(float fValue)    {        for (int i = 0; i < scrollViewItems.Count; i++)        {            EnhanceItem itemScript = scrollViewItems[i];            float xValue = GetXPosValue(fValue, dHorizontalValues[itemScript.scrollViewItemIndex]);            float scaleValue = GetScaleValue(fValue, dHorizontalValues[itemScript.scrollViewItemIndex]);            itemScript.UpdateScrollViewItems(xValue, yPositionValue, scaleValue);        }    }    void Update()    {        currentDuration += Time.deltaTime;        if (currentDuration > duration)        {            // 更新完畢設定選中item的對象即可            currentDuration = duration;            if(centerItem != null)                centerItem.SetSelectColor(true);            if(preCenterItem != null)                preCenterItem.SetSelectColor(false);            canChangeItem = true;        }        SortDepth();        float percent = currentDuration / duration;        horizontalValue = Mathf.Lerp(originHorizontalValue, horizontalTargetValue, percent);        UpdateEnhanceScrollView(horizontalValue);    }

控制層級

只有正確的層級控制,才能夠保證"不穿幫",上文也說過,也可以通過AnimationCurve做一個層級曲線,在當前item的時間下面該item的depth或者層級應該是多少,該demo採用的是比較粗暴的list排序方法,按照每個item距離"螢幕的遠近"其實就是scale係數,判斷哪個item在前,哪個在後面,當然也有些問題,如果距離相同,可能存在item相互打架的可能(這個可以通過控制scaleCurve進行控制)
該Demo使用的UITexture控制層級(其他的任何方式原理一樣,只是處理對象不一樣,用mesh實現,那就是z軸等等)
具體實現如下:

public void SortDepth()    {        textureTargets.Sort(new CompareDepthMethod());        for (int i = 0; i < textureTargets.Count; i++)            textureTargets[i].depth = i;    }    /// <summary>    /// 用於層級對比介面    /// </summary>    public class CompareDepthMethod : IComparer<UITexture>    {        public int Compare(UITexture left, UITexture right)        {            if (left.transform.localScale.x > right.transform.localScale.x)                return 1;            else if (left.transform.localScale.x < right.transform.localScale.x)                return -1;            else                return 0;        }    }

實現滾動迴圈

說道迴圈滾動,因為我們使用到了AnimationCurve,先天性的動畫曲線會有三種模式一種是pingpong,loop,一種是clamp,其中我們需要的是LOOP,沒聽錯這就是滾動迴圈的關鍵點(我們的縮放曲線,位移係數曲線從0到1的效果類比完畢,如果我們繼續向前增加時間流水值,那麼進入到下一個曲線的時候,所有的item都會反過來進行採樣曲線值,就能夠巧妙的實現迴圈效果(縮放係數,位移係數))如果不理解的,可以自己設定一個AnimationCurve,研究下,下面示意:

代碼部分只是需要知道,如果點擊了一個Item將該item移動到中心對應的時間流應該往前或者往後走多少

    /// <summary>    /// 獲得當前要移動到中心的Item需要移動的factor間隔數    /// </summary>    private int GetMoveCurveFactorCount(float targetXPos)    {        int centerIndex = scrollViewItems.Count / 2;        for (int i = 0; i < scrollViewItems.Count;i++ )        {            float factor = (0.5f - dFactor * (centerIndex - i));            float tempPosX = positionCurve.Evaluate(factor) * posCurveFactor;            if (Mathf.Abs(targetXPos - tempPosX) < 0.01f)                return Mathf.Abs(i - centerIndex);        }        return -1;    }

注意問題
  1. 製作曲線,記得保證0-1時間軸填充完畢,這樣在進行迴圈處理的時候才不會出現偏差
  2. 額,如果自己用這種方法嘗試的朋友,如果有問題,請仔細查看Demo中的參數即可......(主要就是曲線製作問題)

該Demo使用的NGUI,雖然筆者沒有用過UGUI,我想任何一個介面Tools都可以通過該方法實現,因為共同點一樣,只是層級處理,縮放處理有區別而已

實現效果




改進目標

該項目還有許多需要改進的地方,以後花時間繼續完善

  • 支援Editor模式下的編輯,不用運行即可查看效果(這個應該是最關鍵的功能)
  • 支援偶數個Item進行滑動
  • 支援Drag操作
  • 支援和NGUI類似的DragScrollView和CenterOnChild功能
  • 最佳化每個Item的層級設定演算法效率
  • 最佳化更新每個Item位置,縮放演算法效率

期待1.1版本吧~

Demo地址

裡麵包含了NGUI3.6.6版本,所有工程有點大
項目工程地址:http://download.csdn.net/detail/fredomyan/8908891

APK測試安裝地址:http://pan.baidu.com/s/1bnfPasJ

總結

所有的內容都講述完畢,如果這篇文章能夠協助到您獲得對看到結束的朋友有一個簡單的啟發,請支援下~,文中存在錯誤或者描述不清楚的也請指正,共同交流學習,最好的方法就是直接下載Demo,然後看下邏輯和動畫曲線的設定參數

歡迎轉載,請註明出處~

By 漂流燕(Andy)



著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.