天天看點

Unity-ScrollRect-循環播放圖檔(确實沒有轉載是真的)

都在代碼和代碼注釋裡了

發表在這裡我還是有私心想要問問題的:

是因為自己在使用時發現,Unity會調用兩次通過繼承來的PictureScrollView的Start函數兩次,

我并不能想明白是怎麼回事,還請有了解的指點一下:)先謝謝能給我指點的各位了;)

而且我寫的這個代碼當使用者按住滑鼠不松開一直向某個方向拖動的話就不會循環顯示圖檔了,交換一次隻會運作,即隻交換一張對應圖檔

我自己所擺放的預制體樣式

Unity-ScrollRect-循環播放圖檔(确實沒有轉載是真的)
Unity-ScrollRect-循環播放圖檔(确實沒有轉載是真的)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
/// 
/// 繼承自UnityEngine.UI的ScrollRect
/// 
public class PictureScrollView : ScrollRect
{
    Vector3 v_OldContenPos = Vector3.zero;
    float size = 0;
    float contentDeltaPos = 0;
    float moveDirection = 0;
    int count = 0;
    bool isDrag = true;
    bool isStillMove = false;
    /// 
    /// 存儲content下的子物體
    /// 
    Button[] buttonElements = null;
    public delegate void Func(bool b);
    /// 
    /// 不在拖動和拖動後持續移動的狀态下,要進行的操作
    /// 
    public Func DisMove;

    void StopAction()
    {
        DisMove(false);
    }

    protected override void Start()
    {
        base.Start();

        buttonElements = content.GetComponentsInChildren              ();
        int length = buttonElements.Length;
        for (int i = 0; i < length; i++)
        {
            buttonElements[i].onClick.AddListener(StopAction);
        }
        //在這裡設定了一下content的錨點
        content.GetComponent
    
     ().anchorMin = new Vector2(0,0.5f) ;
        content.GetComponent
     
      ().anchorMax = new Vector2(0, 0.5f);
        
        //儲存元素容器的初始坐标
        v_OldContenPos = content.localPosition;
        //擷取子物體的數量
        count = content.childCount;
        //Debug.Log(count);
        //該方法會被調用兩次,不進行判斷第一次會有content子對象數量為零
        //不知道為什麼會被調用兩次,而且在停止播放程式後還會再調用兩次
        if (count > 0)
        {
            //獲得子物體的寬度
            size = content.GetChild(0).GetComponent
      
       ().sizeDelta.x;
        }

    }

    private void Update()
    {
        if (!isDrag && isStillMove)
        {
            //繼續滑動
            StillScroll();
        }
        
    }

    public override void OnBeginDrag(PointerEventData eventData)
    {
        base.OnBeginDrag(eventData);

    }

    public override void OnDrag(PointerEventData eventData)
    {
        base.OnDrag(eventData);
        //循環滑動
        Scroll();
        DisMove(false);
    }

    public override void OnEndDrag(PointerEventData eventData)
    {
        base.OnEndDrag(eventData);
        isDrag = false;
        isStillMove = true;
    }

    /// 
        /// 循環滑動 /// 
    void Scroll()
    {

        //容器改變了的位置
        contentDeltaPos = content.position.x;
        //移動方向
        moveDirection = velocity.x;

        //檢測是否達到交換位置的點
        //當使用按照預制體擺放物體時,向左移-,超過兩倍的單元寬度的位移時
        //将最後一個交換至第一個
        if (contentDeltaPos < -2 * size && isDrag)
        {
            //在有ContentSizeFitter類的管理下,SetAsLastSibling()函數會對子物體排序
            content.GetChild(0).SetAsLastSibling();
            content.localPosition = v_OldContenPos;
        }
        if (contentDeltaPos < -2 * size)
        {
            isDrag = false;
        }
        //當使用按照預制體擺放物體時,向右移+,超過一定長度的位移時
        //将第一個交換至最後一個
        if (contentDeltaPos > 0 && isDrag)
        {
            content.localPosition = v_OldContenPos;
            content.GetChild(count - 1).SetAsFirstSibling();
        }
        if (contentDeltaPos > 1)
        {
            isDrag = false;
        }
        
    }

    /// 
        /// 在拖動(OnDrag())結束後的持續滑動 /// 
    void StillScroll()
    {
        //容器改變了的位置
        contentDeltaPos = content.position.x;
        //移動方向
        moveDirection = velocity.x;
        //檢測是否達到交換位置的點
        //當使用按照預制體擺放物體時,向左移-,超過兩倍的單元寬度的位移時
        //将最後一個交換至第一個
        if (contentDeltaPos < -2 * size && velocity.x <= -0.1)
        {
            //在有ContentSizeFitter類的管理下,SetAsLastSibling()函數會對子物體排序
            content.GetChild(0).SetAsLastSibling();
            content.localPosition = v_OldContenPos;
        }

        //當使用按照預制體擺放物體時,向右移+,超過一定長度的位移時
        //将第一個交換至最後一個
        if (contentDeltaPos > 0 && velocity.x >= 0.1)
        {
            content.localPosition = v_OldContenPos;
            content.GetChild(count - 1).SetAsFirstSibling();
        }

        if (Mathf.Abs(velocity.x) <= 0.1)
        {
            isStillMove = false;
            
        }

        //在這裡改變狀态,主要用于和外部類通訊
        if (DisMove != null)
        {
            DisMove(true);
        }
        
    }


}