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);
      //}

      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 实现效果如下

代码如下

public int totalItemNum;//共有几个单元格

 public int currentIndex;//当前单元格的索引

 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)
   {
    //当前的单元格大于等于单元格的总个数
    if (currentIndex >= totalItemNum-1 )
    {
     Debug.Log("左滑动-------");
     return;
    }
    currentIndex += 1;
    scrollRect.DOHorizontalNormalizedPos(currentBilv += bilv, 0.2f);

    Debug.Log("左滑动");
   }
   else
   {
    Debug.Log("右滑动");
    //当前的单元格大于等于单元格的总个数
    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;
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Unity实现轮盘方式的按钮滚动效果

    近期在项目中,策划给出了一个需求就是,让按钮按照一个轮盘的轨迹进行滑动的效果,经过一番测试,实现了初步的效果. 我这里区分了横向滑动和纵向滑动,这里以纵向滑动为例子进行示范,实现按钮的滑动效果. 首先就是先进行位置初始化: /// <summary> ///从大到小排序,Y轴 /// </summary> private Comparison<CircleScrollRectItemBase> ComparisionY = delegate (CircleScrollR

  • Unity实现游戏卡牌滚动效果

    最近项目中的活动面板要做来回滚动卡牌预览效果,感觉自己来写的话,也能写,但是可能会比较耗时,看到Github上有开源的项目,于是就借用了,Github的资源地址,感谢作者的分享. 本篇博客旨在告诉大家如何利用这个插件. 插件的核心在于工程中的6个脚本,以下是六个脚本的源码: DragEnhanceView.cs using UnityEngine; using System.Collections; using UnityEngine.UI; using UnityEngine.EventSys

  • Unity实现3D循环滚动效果

    本文实例为大家分享了Unity实现3D循环滚动效果展示的具体代码,供大家参考,具体内容如下 然后通过SetDepthAndPosition这个方法,实现图片的空间空间展开 Z轴和Y轴,系数是一样的 经过上面设置,空间就摆开了 using UnityEngine; using System.Collections; using System.Collections.Generic; public class SelectRole : MonoBehaviour { public GameObjec

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

    本文实例为大家分享了Unity3D UGUI实现缩放循环拖动卡牌展示的具体代码,供大家参考,具体内容如下 需求:游戏中展示卡牌这种效果也是蛮酷炫并且使用的一种常见效果,下面我们就来实现以下这个效果是如何实现. 思考:第一看看到这个效果,我们首先会想到UGUI里面的ScrollRect,当然也可以用ScrollRect来实现缩短ContentSize的width来自动实现重叠效果,然后中间左右的卡牌通过计算来显示缩放,这里我并没有用这种思路来实现,我提供另外一种思路,就是自己去计算当前每个卡牌的位

  • Unity3D利用DoTween实现卡牌翻转效果

    利用Unity的UGUI制作了2D卡牌翻转的效果,如果是sprite对象的话,原理应该也是一样的,以下是效果图 图1 卡牌翻转效果 关于DoTween DoTween是一款十分强大且好用的动画效果插件,有免费版和收费版,免费版就可以满足大部分需求了,在Unity Assets Store里就可以下载,在本效果里就用了DoTween的旋转功能. 设计思路 创建一个空物体,空物体下有两个image对象,一个是正面,一个是背面.假设我们从正面开始,则初始状态下正面的旋转角度为(0,0,0) (0,0,

  • Android编程实现图片的浏览、缩放、拖动和自动居中效果

    本文实例讲述了Android编程实现图片的浏览.缩放.拖动和自动居中效果的方法.分享给大家供大家参考,具体如下: Touch.java /** * 图片浏览.缩放.拖动.自动居中 */ public class Touch extends Activity implements OnTouchListener { Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); DisplayMetrics dm; ImageVie

  • Unity实现卡牌翻动效果

    本文实例为大家分享了Unity实现卡牌翻动效果展示的具体代码,供大家参考,具体内容如下 事实上这是项目需要,我改的一个代码,实际上就是利用unity的一些基础属性实现其效果.啥也不多说了,先上原代码: /// Credit Mrs. YakaYocha /// Sourced from - https://www.youtube.com/channel/UCHp8LZ_0-iCvl-5pjHATsgw /// Please donate: https://www.paypal.com/cgi-b

  • Android利用Camera实现中轴3D卡牌翻转效果

    在Android系统API中,有两个Camera类: android.graphics.Camera android.hardware.Camera 第二个应用于手机硬件中的相机相关的操作,本文讲述的是利用第一个Camera类实现中轴3D转换的卡牌翻转效果,开始之前,先看一下Android系统中的坐标系: 对应于三维坐标系中的三个方向,Camera提供了三种旋转方法: rotateX() rotateY() rotateX() 调用这三种方法,传入旋转角度参数,即可实现视图沿着坐标轴旋转的功能.

  • 利用Vue实现卡牌翻转的特效

    目录 前言 实现 鼠标移入选中效果 卡片翻转效果 完整代码 结语 前言 今天是正月初九,也是活动的倒数第二天,复工都三天了,而我三篇春节文章还没写完,实在是太混了!这次带来的是一个春节抽福卡页面,采用卡牌翻转的形式. 实现 以下所有的实现都是基于Vue2 来编写的. (别骂了,我这就去学 Vue3 鼠标移入选中效果 从上面的效果图可以看到,当鼠标移动到某张福卡的时候,这张福卡就会放大,其余未被选中的卡片就会缩小且变得模糊.这样的视觉效果是通过 CSS 和 JS 一起控制的. 其实只用 css 也

  • js CSS3实现卡牌旋转切换效果

    我们经常会在游戏里看到一些几张卡牌左右切换的效果,中间的一张最突出醒目,向左或向右滑动可切换到另一张,今天我们就用CSS3来实现下这种效果. 我们先来看个demo,具体的样式各位可以自己调整: (PC下可点击按钮切换,移动端可左右滑动切换) 从效果上我们可以看到,这5个div可以左右的切换,每次切换时总会有一个在中间显眼的位置进行展示.在切换时,看起来是div进行了移动,进行了DOM的增删操作.但是如果审查下元素,就能看到,DOM元素没有变换位置,它依然在那个位置,我们只是切换了每个元素上的cl

  • JS实现可缩放、拖动、关闭和最小化的浮动窗口完整实例

    本文实例讲述了JS实现可缩放.拖动.关闭和最小化的浮动窗口方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999

  • Android实现ImageView图片缩放和拖动

    今天我们来编写一个缩放效果的ImageView ,网上有很多人都讲了这些.但有许多人都直接使用了库文件, 那么我们今天做的是直接上代码编写一个拖动和缩放的ImageView,具体看效果图 那么简单了分析一下.在手机上缩放图片和拖动要用到什么?手指对不对 那么控件上什么事件和手机有关.View.OnTouchListener 对不对. ok,那么先新建一个Class ··· public class BaseDragZoomImageView extends ImageView implement

随机推荐