小編給大家分享一下Unity3D UGUI如何實(shí)現(xiàn)縮放循環(huán)拖動(dòng)卡牌展示效果,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
創(chuàng)新互聯(lián)建站長期為上千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為蒼梧企業(yè)提供專業(yè)的成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì),蒼梧網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
思考:第一看看到這個(gè)效果,我們首先會(huì)想到UGUI里面的ScrollRect,當(dāng)然也可以用ScrollRect來實(shí)現(xiàn)縮短ContentSize的width來自動(dòng)實(shí)現(xiàn)重疊效果,然后中間左右的卡牌通過計(jì)算來顯示縮放,這里我并沒有用這種思路來實(shí)現(xiàn),我提供另外一種思路,就是自己去計(jì)算當(dāng)前每個(gè)卡牌的位置和縮放值,不用UGUI的內(nèi)置組件。
CODE:
1.卡牌拖動(dòng)組件:
using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public enum DragPosition { Left, Right, Up, Down, } [RequireComponent(typeof(Image))] public class CDragOnCard : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public bool dragOnSurfaces = true; public ScrollRect m_ScrollRect = null; public CFixGridRect m_FixGridRect = null; private RectTransform m_DraggingPlane; public bool isVertical = false; private bool isSelf = false; private DragPosition m_dragPosition = DragPosition.Left; public System.Action<DragPosition> DragCallBack = null; public void OnBeginDrag(PointerEventData eventData) { Vector2 touchDeltaPosition = Vector2.zero; #if UNITY_EDITOR float delta_x = Input.GetAxis("Mouse X"); float delta_y = Input.GetAxis("Mouse Y"); touchDeltaPosition = new Vector2(delta_x, delta_y); #elif UNITY_ANDROID || UNITY_IPHONE touchDeltaPosition = Input.GetTouch(0).deltaPosition; #endif if (isVertical) { if(touchDeltaPosition.y > 0) { UnityEngine.Debug.Log("上拖"); m_dragPosition = DragPosition.Up; } else { UnityEngine.Debug.Log("下拖"); m_dragPosition = DragPosition.Down; } if (Mathf.Abs(touchDeltaPosition.x) > Mathf.Abs(touchDeltaPosition.y)) { isSelf = true; var canvas = FindInParents<Canvas>(gameObject); if (canvas == null) return; if (dragOnSurfaces) m_DraggingPlane = transform as RectTransform; else m_DraggingPlane = canvas.transform as RectTransform; } else { isSelf = false; if (m_ScrollRect != null) m_ScrollRect.OnBeginDrag(eventData); } } else //水平 { if (touchDeltaPosition.x > 0) { UnityEngine.Debug.Log("右移"); m_dragPosition = DragPosition.Right; } else { UnityEngine.Debug.Log("左移"); m_dragPosition = DragPosition.Left; } if (Mathf.Abs(touchDeltaPosition.x) < Mathf.Abs(touchDeltaPosition.y)) { isSelf = true; var canvas = FindInParents<Canvas>(gameObject); if (canvas == null) return; if (dragOnSurfaces) m_DraggingPlane = transform as RectTransform; else m_DraggingPlane = canvas.transform as RectTransform; } else { isSelf = false; if (m_ScrollRect != null) m_ScrollRect.OnBeginDrag(eventData); } } } public void OnDrag(PointerEventData data) { if (isSelf) { } else { if (m_ScrollRect != null) m_ScrollRect.OnDrag(data); } } public void OnEndDrag(PointerEventData eventData) { if (isSelf) { } else { if (m_ScrollRect != null) m_ScrollRect.OnEndDrag(eventData); if (m_FixGridRect != null) m_FixGridRect.OnEndDrag(eventData); } if (DragCallBack != null) DragCallBack(m_dragPosition); } static public T FindInParents<T>(GameObject go) where T : Component { if (go == null) return null; var comp = go.GetComponent<T>(); if (comp != null) return comp; Transform t = go.transform.parent; while (t != null && comp == null) { comp = t.gameObject.GetComponent<T>(); t = t.parent; } return comp; } }
2.卡牌組件
using UnityEngine; using System.Collections; using UnityEngine.UI; public class EnhanceItem : MonoBehaviour { // 在ScrollViewitem中的索引 // 定位當(dāng)前的位置和縮放 public int scrollViewItemIndex = 0; public bool inRightArea = false; private Vector3 targetPos = Vector3.one; private Vector3 targetScale = Vector3.one; private Transform mTrs; private Image mImage; private int index = 1; public void Init(int cardIndex = 1) { index = cardIndex; mTrs = this.transform; mImage = this.GetComponent<Image>(); mImage.sprite = Resources.Load<Sprite>(string.Format("Texture/card_bg_big_{0}", cardIndex % 6 + 1)); this.gameObject.GetComponent<Button>().onClick.AddListener(delegate () { OnClickScrollViewItem(); }); } // 當(dāng)點(diǎn)擊Item,將該item移動(dòng)到中間位置 private void OnClickScrollViewItem() { Debug.LogError("點(diǎn)擊" + index); EnhancelScrollView.GetInstance().SetHorizontalTargetItemIndex(scrollViewItemIndex); } /// <summary> /// 更新該Item的縮放和位移 /// </summary> public void UpdateScrollViewItems(float xValue, float yValue, float scaleValue) { targetPos.x = xValue; targetPos.y = yValue; targetScale.x = targetScale.y = scaleValue; mTrs.localPosition = targetPos; mTrs.localScale = targetScale; } public void SetSelectColor(bool isCenter) { if (mImage == null) mImage = this.GetComponent<Image>(); if (isCenter) mImage.color = Color.white; else mImage.color = Color.gray; } }
3.自定義的ScrollView組件
using UnityEngine; using System.Collections; using System.Collections.Generic; using UnityEngine.UI; public class EnhancelScrollView : MonoBehaviour { public AnimationCurve scaleCurve; public AnimationCurve positionCurve; public float posCurveFactor = 500.0f; public float yPositionValue = 46.0f; public List<EnhanceItem> scrollViewItems = new List<EnhanceItem>(); private List<Image> imageTargets = new List<Image>(); private EnhanceItem centerItem; private EnhanceItem preCenterItem; private bool canChangeItem = true; public float dFactor = 0.2f; private float[] moveHorizontalValues; private float[] dHorizontalValues; public float horizontalValue = 0.0f; public float horizontalTargetValue = 0.1f; private float originHorizontalValue = 0.1f; public float duration = 0.2f; private float currentDuration = 0.0f; private static EnhancelScrollView instance; private bool isInit = false; public static EnhancelScrollView GetInstance() { return instance; } void Awake() { instance = this; } public void Init() { if ((scrollViewItems.Count % 2) == 0) { Debug.LogError("item count is invaild,please set odd count! just support odd count."); } if (moveHorizontalValues == null) moveHorizontalValues = new float[scrollViewItems.Count]; if (dHorizontalValues == null) dHorizontalValues = new float[scrollViewItems.Count]; if (imageTargets == null) imageTargets = new List<Image>(); int centerIndex = scrollViewItems.Count / 2; for (int i = 0; i < scrollViewItems.Count; i++) { scrollViewItems[i].scrollViewItemIndex = i; Image tempImage = scrollViewItems[i].gameObject.GetComponent<Image>(); imageTargets.Add(tempImage); dHorizontalValues[i] = dFactor * (centerIndex - i); dHorizontalValues[centerIndex] = 0.0f; moveHorizontalValues[i] = 0.5f - dHorizontalValues[i]; scrollViewItems[i].SetSelectColor(false); } //centerItem = scrollViewItems[centerIndex]; canChangeItem = true; isInit = true; } 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() { if (!isInit) return; currentDuration += Time.deltaTime; SortDepth(); if (currentDuration > duration) { currentDuration = duration; //if (centerItem != null) //{ // centerItem.SetSelectColor(true); //} if (centerItem == null) { var obj = transform.GetChild(transform.childCount - 1); if (obj != null) centerItem = obj.GetComponent<EnhanceItem>(); if (centerItem != null) centerItem.SetSelectColor(true); } else centerItem.SetSelectColor(true); if (preCenterItem != null) preCenterItem.SetSelectColor(false); canChangeItem = true; } float percent = currentDuration / duration; horizontalValue = Mathf.Lerp(originHorizontalValue, horizontalTargetValue, percent); UpdateEnhanceScrollView(horizontalValue); } private float GetScaleValue(float sliderValue, float added) { float scaleValue = scaleCurve.Evaluate(sliderValue + added); return scaleValue; } private float GetXPosValue(float sliderValue, float added) { float evaluateValue = positionCurve.Evaluate(sliderValue + added) * posCurveFactor; return evaluateValue; } public void SortDepth() { imageTargets.Sort(new CompareDepthMethod()); for (int i = 0; i < imageTargets.Count; i++) imageTargets[i].transform.SetSiblingIndex(i); } public class CompareDepthMethod : IComparer<Image> { public int Compare(Image left, Image 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; } } 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; } public void SetHorizontalTargetItemIndex(int itemIndex) { if (!canChangeItem) return; EnhanceItem item = scrollViewItems[itemIndex]; if (centerItem == item) return; canChangeItem = false; preCenterItem = centerItem; centerItem = item; float centerXValue = positionCurve.Evaluate(0.5f) * posCurveFactor; bool isRight = false; if (item.transform.localPosition.x > centerXValue) isRight = true; int moveIndexCount = GetMoveCurveFactorCount(item.transform.localPosition.x); if (moveIndexCount == -1) { moveIndexCount = 1; } float dvalue = 0.0f; if (isRight) dvalue = -dFactor * moveIndexCount; else dvalue = dFactor * moveIndexCount; horizontalTargetValue += dvalue; currentDuration = 0.0f; originHorizontalValue = horizontalValue; } public void OnBtnRightClick() { if (!canChangeItem) return; int targetIndex = centerItem.scrollViewItemIndex + 1; if (targetIndex > scrollViewItems.Count - 1) targetIndex = 0; SetHorizontalTargetItemIndex(targetIndex); } public void OnBtnLeftClick() { if (!canChangeItem) return; int targetIndex = centerItem.scrollViewItemIndex - 1; if (targetIndex < 0) targetIndex = scrollViewItems.Count - 1; SetHorizontalTargetItemIndex(targetIndex); } }
上面的代碼好像不能用 我自己寫了兩種方法
1 使用 Scroll View 實(shí)現(xiàn)效果如下
代碼如下
public int totalItemNum;//共有幾個(gè)單元格 public int currentIndex;//當(dāng)前單元格的索引 private float bilv ; public float currentBilv = 0; private void Awake() { scrollRect = GetComponent<ScrollRect>(); scrollRect.horizontalNormalizedPosition =0; } // Use this for initialization void Start () { Button[] button = scrollRect.content.GetComponentsInChildren<Button>(); totalItemNum= button.Length; bilv = 1 / (totalItemNum - 1.00f); } public void OnBeginDrag(PointerEventData eventData) { beginMousePositionX = Input.mousePosition.x; } public void OnEndDrag(PointerEventData eventData) { float offSetX = 0; endMousePositionX = Input.mousePosition.x; offSetX = beginMousePositionX - endMousePositionX; if (Mathf.Abs(offSetX)>firstItemLength) { if (offSetX>0) { //當(dāng)前的單元格大于等于單元格的總個(gè)數(shù) if (currentIndex >= totalItemNum-1 ) { Debug.Log("左滑動(dòng)-------"); return; } currentIndex += 1; scrollRect.DOHorizontalNormalizedPos(currentBilv += bilv, 0.2f); Debug.Log("左滑動(dòng)"); } else { Debug.Log("右滑動(dòng)"); //當(dāng)前的單元格大于等于單元格的總個(gè)數(shù) if ( currentIndex < 1) { return; } currentIndex -= 1; scrollRect.DOHorizontalNormalizedPos(currentBilv -= bilv, 0.2f); } } }
using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.UI; public class ThreePage1 : MonoBehaviour { public GameObject[] images; int currentIndex; public float DistancesNum = 250; public float min = 0.8f; public float max = 1.4f; public float speed = 0.2f; public float Alpha = 0.8f; void Start () { InitRectTranform(); } public void InitRectTranform() { currentIndex = images.Length / 2; for (int i = currentIndex + 1; i < images.Length; i++) { images[i].GetComponent<RectTransform>().anchoredPosition = new Vector3((i - currentIndex) * DistancesNum, 0, 0); } int num = 0; for (int i = currentIndex; i >= 0; i--) { images[i].GetComponent<RectTransform>().anchoredPosition = new Vector3(-num * DistancesNum, 0, 0); num++; } foreach (var item in images) { if (item != images[currentIndex]) { item.GetComponent<RectTransform>().localScale = new Vector3(min, min); item.GetComponent<Image>().color = new Color(1, 1, 1, Alpha); } else { item.GetComponent<RectTransform>().localScale = new Vector3(max, max); } } } public void Left() { ButtonManager._Instances.PlayInput(); OnLeftButtonClick(); } public void OnLeftButtonClick() { if (currentIndex < images.Length-1) { foreach (GameObject item in images) { (item.GetComponent<RectTransform>()).DOAnchorPosX(item.GetComponent<RectTransform>().anchoredPosition.x- DistancesNum, speed); } images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, Alpha); images[currentIndex].GetComponent<RectTransform>().DOScale(min, speed); currentIndex += 1; images[currentIndex].GetComponent<RectTransform>().DOScale(max, speed); images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, 1f); } } public void Right() { ButtonManager._Instances.PlayInput(); OnRightButtonClick(); } public void OnRightButtonClick() { if (currentIndex > 0) { foreach (GameObject item in images) { (item.GetComponent<RectTransform>()).DOAnchorPosX(item.GetComponent<RectTransform>().anchoredPosition.x + DistancesNum, speed); } images[currentIndex].GetComponent<RectTransform>().DOScale(min, speed); images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, Alpha); currentIndex -= 1; images[currentIndex].GetComponent<RectTransform>().DOScale(max, speed); images[currentIndex].GetComponent<Image>().color = new Color(1, 1, 1, 1f); } } private void OnEnable() { isOn = true; timess = 0; //jarodInputController.IsShiYong = true; } private void OnDisable() { InitRectTranform(); jarodInputController.IsShiYong = false; } }
以上是“Unity3D UGUI如何實(shí)現(xiàn)縮放循環(huán)拖動(dòng)卡牌展示效果”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站名稱:Unity3DUGUI如何實(shí)現(xiàn)縮放循環(huán)拖動(dòng)卡牌展示效果
分享網(wǎng)址:http://muchs.cn/article12/pisddc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、網(wǎng)站設(shè)計(jì)、搜索引擎優(yōu)化、網(wǎng)站內(nèi)鏈、移動(dòng)網(wǎng)站建設(shè)、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)