Unity3D UGUI实现缩放循环拖动卡牌展示效果

这篇文章主要为大家详细介绍了Unity3D UGUI实现缩放循环拖动展示卡牌效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Unity3D UGUI实现缩放循环拖动卡牌展示的具体代码,供大家参考,具体内容如下

需求:游戏中展示卡牌这种效果也是蛮酷炫并且使用的一种常见效果,下面我们就来实现以下这个效果是如何实现。 

思考:第一看看到这个效果,我们首先会想到UGUI里面的ScrollRect,当然也可以用ScrollRect来实现缩短ContentSize的width来自动实现重叠效果,然后中间左右的卡牌通过计算来显示缩放,这里我并没有用这种思路来实现,我提供另外一种思路,就是自己去计算当前每个卡牌的位置和缩放值,不用UGUI的内置组件。

CODE:

1.卡牌拖动组件:


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中的索引
 // 定位当前的位置和缩放
 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(); });
 }
 
 // 当点击Item,将该item移动到中间位置
 private void OnClickScrollViewItem()
 {
  Debug.LogError("点击" + 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);
   /

本文标题为:Unity3D UGUI实现缩放循环拖动卡牌展示效果

基础教程推荐