您好,登錄后才能下訂單哦!
本文實(shí)例為大家分享了Unity實(shí)現(xiàn)卡牌翻動(dòng)效果展示的具體代碼,供大家參考,具體內(nèi)容如下
事實(shí)上這是項(xiàng)目需要,我改的一個(gè)代碼,實(shí)際上就是利用unity的一些基礎(chǔ)屬性實(shí)現(xiàn)其效果。啥也不多說(shuō)了,先上原代碼:
/// Credit Mrs. YakaYocha /// Sourced from - https://www.youtube.com/channel/UCHp8LZ_0-iCvl-5pjHATsgw /// Please donate: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RJ8D9FRFQF9VS using UnityEngine.Events; namespace UnityEngine.UI.Extensions { [RequireComponent(typeof(ScrollRect))] [AddComponentMenu("Layout/Extensions/Vertical Scroller")] public class UIVerticalScroller : MonoBehaviour { [Tooltip("Scrollable area (content of desired ScrollRect)")] public RectTransform _scrollingPanel; [Tooltip("Elements to populate inside the scroller")] public GameObject[] _arrayOfElements; [Tooltip("Center display area (position of zoomed content)")] public RectTransform _center; [Tooltip("Select the item to be in center on start. (optional)")] public int StartingIndex = -1; [Tooltip("Button to go to the next page. (optional)")] public GameObject ScrollUpButton; [Tooltip("Button to go to the previous page. (optional)")] public GameObject ScrollDownButton; [Tooltip("Event fired when a specific item is clicked, exposes index number of item. (optional)")] public UnityEvent<int> ButtonClicked; private float[] distReposition; private float[] distance; //private int elementsDistance; private int minElementsNum; private int elementLength; //private int elementHalfLength; private float deltaY; private string result; public UIVerticalScroller() { } public UIVerticalScroller(RectTransform scrollingPanel, GameObject[] arrayOfElements, RectTransform center) { _scrollingPanel = scrollingPanel; _arrayOfElements = arrayOfElements; _center = center; } public void Awake() { var scrollRect = GetComponent<ScrollRect>(); if (!_scrollingPanel) { _scrollingPanel = scrollRect.content; } if (!_center) { Debug.LogError("Please define the RectTransform for the Center viewport of the scrollable area"); } if (_arrayOfElements == null || _arrayOfElements.Length == 0) { var childCount = scrollRect.content.childCount; if (childCount > 0) { _arrayOfElements = new GameObject[childCount]; for (int i = 0; i < childCount; i++) { _arrayOfElements[i] = scrollRect.content.GetChild(i).gameObject; } } } } public void Start() { if (_arrayOfElements.Length < 1) { Debug.Log("No child content found, exiting.."); return; } elementLength = _arrayOfElements.Length; distance = new float[elementLength]; distReposition = new float[elementLength]; //get distance between buttons //elementsDistance = (int)Mathf.Abs(_arrayOfElements[1].GetComponent<RectTransform>().anchoredPosition.y - _arrayOfElements[0].GetComponent<RectTransform>().anchoredPosition.y); deltaY = _arrayOfElements[0].GetComponent<RectTransform>().rect.height * elementLength / 3 * 2; Vector2 startPosition = new Vector2(_scrollingPanel.anchoredPosition.x, -deltaY); _scrollingPanel.anchoredPosition = startPosition; for (var i = 0; i < _arrayOfElements.Length; i++) { AddListener(_arrayOfElements[i], i); } if (ScrollUpButton) ScrollUpButton.GetComponent<Button>().onClick.AddListener(() => { ScrollUp(); }); if (ScrollDownButton) ScrollDownButton.GetComponent<Button>().onClick.AddListener(() => { ScrollDown(); }); if (StartingIndex > -1) { StartingIndex = StartingIndex > _arrayOfElements.Length ? _arrayOfElements.Length - 1 : StartingIndex; SnapToElement(StartingIndex); } } private void AddListener(GameObject button, int index) { button.GetComponent<Button>().onClick.AddListener(() => DoSomething(index)); } private void DoSomething(int index) { if (ButtonClicked != null) { ButtonClicked.Invoke(index); } } public void Update() { if (_arrayOfElements.Length < 1) { return; } for (var i = 0; i < elementLength; i++) { distReposition[i] = _center.GetComponent<RectTransform>().position.y - _arrayOfElements[i].GetComponent<RectTransform>().position.y; distance[i] = Mathf.Abs(distReposition[i]); //Magnifying effect float scale = Mathf.Max(0.7f, 1 / (1 + distance[i] / 200)); _arrayOfElements[i].GetComponent<RectTransform>().transform.localScale = new Vector3(scale, scale, 1f); } float minDistance = Mathf.Min(distance); for (var i = 0; i < elementLength; i++) { _arrayOfElements[i].GetComponent<CanvasGroup>().interactable = false; if (minDistance == distance[i]) { minElementsNum = i; _arrayOfElements[i].GetComponent<CanvasGroup>().interactable = true; result = _arrayOfElements[i].GetComponentInChildren<Text>().text; } } ScrollingElements(-_arrayOfElements[minElementsNum].GetComponent<RectTransform>().anchoredPosition.y); } private void ScrollingElements(float position) { float newY = Mathf.Lerp(_scrollingPanel.anchoredPosition.y, position, Time.deltaTime * 1f); Vector2 newPosition = new Vector2(_scrollingPanel.anchoredPosition.x, newY); _scrollingPanel.anchoredPosition = newPosition; } public string GetResults() { return result; } public void SnapToElement(int element) { float deltaElementPositionY = _arrayOfElements[0].GetComponent<RectTransform>().rect.height * element; Vector2 newPosition = new Vector2(_scrollingPanel.anchoredPosition.x, -deltaElementPositionY); _scrollingPanel.anchoredPosition = newPosition; } public void ScrollUp() { float deltaUp = _arrayOfElements[0].GetComponent<RectTransform>().rect.height / 1.2f; Vector2 newPositionUp = new Vector2(_scrollingPanel.anchoredPosition.x, _scrollingPanel.anchoredPosition.y - deltaUp); _scrollingPanel.anchoredPosition = Vector2.Lerp(_scrollingPanel.anchoredPosition, newPositionUp, 1); } public void ScrollDown() { float deltaDown = _arrayOfElements[0].GetComponent<RectTransform>().rect.height / 1.2f; Vector2 newPositionDown = new Vector2(_scrollingPanel.anchoredPosition.x, _scrollingPanel.anchoredPosition.y + deltaDown); _scrollingPanel.anchoredPosition = newPositionDown; } } }
源代碼是上下滑動(dòng)的,再上我改過(guò)之后的代碼,左右滑動(dòng)的;
/// Credit Mrs. YakaYocha /// Sourced from - https://www.youtube.com/channel/UCHp8LZ_0-iCvl-5pjHATsgw /// Please donate: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RJ8D9FRFQF9VS using UnityEngine.Events; namespace UnityEngine.UI.Extensions { [RequireComponent(typeof(ScrollRect))] [AddComponentMenu("Layout/Extensions/Vertical Scroller")] public class UIVerticalScrollerMove : MonoBehaviour { [Tooltip("Scrollable area (content of desired ScrollRect)")] public RectTransform _scrollingPanel;//展示面板 [Tooltip("Elements to populate inside the scroller")] public GameObject[] _arrayOfElements;//長(zhǎng)度元素 [Tooltip("Center display area (position of zoomed content)")] public RectTransform _center;//位置 [Tooltip("Select the item to be in center on start. (optional)")] public int StartingIndex = -1;//初始指針(外界提供) [Tooltip("Button to go to the next page. (optional)")] public GameObject ScrollLeftButton;//左按鈕 [Tooltip("Button to go to the previous page. (optional)")] public GameObject ScrollRightButton;//右按鈕 [Tooltip("Event fired when a specific item is clicked, exposes index number of item. (optional)")] public UnityEvent<int> ButtonClicked;//按鈕點(diǎn)擊 private float[] distReposition;//長(zhǎng)度改變 private float[] distance;//長(zhǎng)度列表 //private int elementsDistance; private int minElementsNum;//最小元素?cái)?shù) private int elementLength;//元素長(zhǎng)度 //private int elementHalfLength; private float deltaX;//移動(dòng)x private string result;//結(jié)果 public UIVerticalScrollerMove() { }//構(gòu)造函數(shù) public UIVerticalScrollerMove(RectTransform scrollingPanel, GameObject[] arrayOfElements, RectTransform center) { _scrollingPanel = scrollingPanel; _arrayOfElements = arrayOfElements; _center = center; } //初始化啟動(dòng) public void Awake() { var scrollRect = GetComponent<ScrollRect>();//獲取到排列 if (!_scrollingPanel) { _scrollingPanel = scrollRect.content;//如果不是展示面板,獲取該物體的可滾動(dòng)的面板 } if (!_center)//如果設(shè)置不成功,打印失敗 { Debug.LogError("Please define the RectTransform for the Center viewport of the scrollable area"); } if (_arrayOfElements == null || _arrayOfElements.Length == 0) { var childCount = scrollRect.content.childCount; if (childCount > 0) { _arrayOfElements = new GameObject[childCount]; for (int i = 0; i < childCount; i++) { _arrayOfElements[i] = scrollRect.content.GetChild(i).gameObject; } } }//獲取子物體的長(zhǎng)度 } //初始化啟動(dòng) public void Start() { if (_arrayOfElements.Length < 1) { Debug.Log("No child content found, exiting.."); return; }//沒(méi)有子物體的時(shí)候,打印尋找失敗 elementLength = _arrayOfElements.Length; distance = new float[elementLength]; distReposition = new float[elementLength];//通過(guò)子物體的長(zhǎng)度定義距離長(zhǎng)度列表與移動(dòng)長(zhǎng)度列表 //get distance between buttons //elementsDistance = (int)Mathf.Abs(_arrayOfElements[1].GetComponent<RectTransform>().anchoredPosition.y - _arrayOfElements[0].GetComponent<RectTransform>().anchoredPosition.y); deltaX = _arrayOfElements[0].GetComponent<RectTransform>().rect.width * elementLength / 3 * 2; Vector2 startPosition = new Vector2( -deltaX,_scrollingPanel.anchoredPosition.y); _scrollingPanel.anchoredPosition = startPosition;//獲取到更改的按鈕 for (var i = 0; i < _arrayOfElements.Length; i++) { AddListener(_arrayOfElements[i], i); }//監(jiān)聽(tīng)每個(gè)按鈕上掛載的方法 //如果左右按鈕的話,分別監(jiān)聽(tīng)不同的方法 if (ScrollLeftButton) ScrollLeftButton.GetComponent<Button>().onClick.AddListener(() => { ScrollLeft(); }); if (ScrollRightButton) ScrollRightButton.GetComponent<Button>().onClick.AddListener(() => { ScrollRight(); }); //比較外界提供的初始指針并進(jìn)行初始定位 if (StartingIndex > -1) { StartingIndex = StartingIndex > _arrayOfElements.Length ? _arrayOfElements.Length - 1 : StartingIndex; SnapToElement(StartingIndex); } } //讓該物體監(jiān)聽(tīng)到自己所對(duì)應(yīng)的事件 private void AddListener(GameObject button, int index) { button.GetComponent<Button>().onClick.AddListener(() => DoSomething(index)); } //index按鈕對(duì)應(yīng)的點(diǎn)擊狀態(tài) private void DoSomething(int index) { if (ButtonClicked != null) { ButtonClicked.Invoke(index); } } //邏輯更新 public void Update() { if (_arrayOfElements.Length < 1) { return; }//子物體為空的時(shí)候返回 for (var i = 0; i < elementLength; i++) { distReposition[i] = _center.GetComponent<RectTransform>().position.x - _arrayOfElements[i].GetComponent<RectTransform>().position.x; distance[i] = Mathf.Abs(distReposition[i]); //Magnifying effect float scale = Mathf.Max(0.7f, 1 / (1 + distance[i] / 200)); _arrayOfElements[i].GetComponent<RectTransform>().transform.localScale = new Vector3(scale, scale, 1f); }//不斷更新可滑動(dòng)面板下面的物體下面的動(dòng)態(tài)數(shù)列 float minDistance = Mathf.Min(distance);//求出最小間距 for (var i = 0; i < elementLength; i++) { _arrayOfElements[i].GetComponent<CanvasGroup>().interactable = false; if (minDistance == distance[i]) { minElementsNum = i; _arrayOfElements[i].GetComponent<CanvasGroup>().interactable = true; result = _arrayOfElements[i].GetComponentInChildren<Text>().text; } }//除了被選中的物體,其余物體都是不可交互的 ScrollingElements(-_arrayOfElements[minElementsNum].GetComponent<RectTransform>().anchoredPosition.x);//不斷向著新坐標(biāo)移動(dòng) } //不斷移動(dòng)坐標(biāo),保證向著目標(biāo)點(diǎn)移動(dòng) private void ScrollingElements(float position) { float newX= Mathf.Lerp(_scrollingPanel.anchoredPosition.x, position, Time.deltaTime * 1f); Vector2 newPosition = new Vector2(newX,_scrollingPanel.anchoredPosition.y); _scrollingPanel.anchoredPosition = newPosition; } public string GetResults() { return result; } //通過(guò)指針計(jì)算該物體在坐標(biāo)欄下的位置 public void SnapToElement(int element) { float deltaElementPositionX = _arrayOfElements[0].GetComponent<RectTransform>().rect.width * element; Vector2 newPosition = new Vector2(-deltaElementPositionX,_scrollingPanel.anchoredPosition.y); _scrollingPanel.anchoredPosition = newPosition; } //左右滑動(dòng) public void ScrollLeft() { float deltaLeft = _arrayOfElements[0].GetComponent<RectTransform>().rect.width / 1.2f; Vector2 newPositionLeft = new Vector2(_scrollingPanel.anchoredPosition.x-deltaLeft, _scrollingPanel.anchoredPosition.y); _scrollingPanel.anchoredPosition = Vector2.Lerp(_scrollingPanel.anchoredPosition,newPositionLeft, 1); } public void ScrollRight() { float deltaRight = _arrayOfElements[0].GetComponent<RectTransform>().rect.width / 1.2f; Vector2 newPositionRight = new Vector2(_scrollingPanel.anchoredPosition.x+deltaRight, _scrollingPanel.anchoredPosition.y); _scrollingPanel.anchoredPosition = newPositionRight; } } }
這是可插件里面的類(lèi)庫(kù),不過(guò)核心邏輯可以用Unity來(lái)重寫(xiě),以上都有注釋。
最后是引用方法:
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.UI.Extensions; public class ScrollingCalendarTest : MonoBehaviour { public RectTransform monthsScrollingPanel; public GameObject monthsButtonPrefab; private GameObject[] monthsButtons; public RectTransform monthCenter; private int monthsSet; UIVerticalScrollerMove monthsVerticalScroller; //Initialize Months //生成預(yù)制體 private void InitializeMonths() { int[] months = new int[12]; monthsButtons = new GameObject[months.Length]; for (int i = 0; i < months.Length; i++) { string month = ""; months[i] = i; GameObject clone = (GameObject)Instantiate(monthsButtonPrefab, new Vector3(i * 380,0, 0), Quaternion.Euler(new Vector3(0, 0, 0))) as GameObject; clone.transform.SetParent(monthsScrollingPanel, false); clone.transform.localScale = new Vector3(1, 1, 1); month = ""+i; clone.GetComponentInChildren<Text>().text = month; clone.name = "Month_" + months[i]; clone.AddComponent<CanvasGroup>(); monthsButtons[i] = clone; } } // Use this for initialization public void Awake() { InitializeMonths(); //Yes Unity complains about this but it doesn't matter in this case. monthsVerticalScroller = new UIVerticalScrollerMove(monthsScrollingPanel, monthsButtons, monthCenter); monthsVerticalScroller.Start(); } public void SetDate() { // monthsSet = int.Parse(inputFieldMonths.text) - 1; monthsVerticalScroller.SnapToElement(monthsSet); } void Update() { monthsVerticalScroller.Update(); string monthString = monthsVerticalScroller.GetResults(); } public void MonthsScrollUp() { monthsVerticalScroller.ScrollLeft(); } public void MonthsScrollDown() { monthsVerticalScroller.ScrollRight(); } }
效果與引用:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。