Unity实现卡牌翻动效果

本文实例为大家分享了Unity实现卡牌翻动效果展示的具体代码,供大家参考,具体内容如下

事实上这是项目需要,我改的一个代码,实际上就是利用unity的一些基础属性实现其效果。啥也不多说了,先上原代码:

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

源代码是上下滑动的,再上我改过之后的代码,左右滑动的;

/// 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;//长度元素
  [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;//按钮点击

  private float[] distReposition;//长度改变
  private float[] distance;//长度列表
  //private int elementsDistance;
  private int minElementsNum;//最小元素数
  private int elementLength;//元素长度
  //private int elementHalfLength;
  private float deltaX;//移动x
  private string result;//结果

  public UIVerticalScrollerMove() { }//构造函数

  public UIVerticalScrollerMove(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);
   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);
   }//监听每个按钮上挂载的方法

   //如果左右按钮的话,分别监听不同的方法
   if (ScrollLeftButton)
    ScrollLeftButton.GetComponent<Button>().onClick.AddListener(() => { ScrollLeft(); });

   if (ScrollRightButton)
    ScrollRightButton.GetComponent<Button>().onClick.AddListener(() => { ScrollRight(); });

   //比较外界提供的初始指针并进行初始定位
   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));
  }

  //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.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);
   }//不断更新可滑动面板下面的物体下面的动态数列
   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);//不断向着新坐标移动
  }

  //不断移动坐标,保证向着目标点移动
  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;
  }

  //通过指针计算该物体在坐标栏下的位置
  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;
  }

  //左右滑动
  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;
  }
 }
}

这是可插件里面的类库,不过核心逻辑可以用Unity来重写,以上都有注释。

最后是引用方法:

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
 //生成预制体
 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();
  }

}

效果与引用:

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

(0)

相关推荐

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

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

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

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

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

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

  • 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() 调用这三种方法,传入旋转角度参数,即可实现视图沿着坐标轴旋转的功能.

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

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

  • Swift洗牌动画效果的实现方法

    目标效果: 点击动画按钮之后每张牌各自旋转 散开到屏幕上半部分的任意位置之后回到初始位置 比较像LOL男刀的技能动画 : ) 1: 创建卡牌对象 for _ in 0...49 { let cardSet = UIImageView(image: UIImage(named: "cardBackLandscape")) self.view.addSubview(cardSet) cardSet.frame = self.landscapeCardBack.frame self.card

  • Unity ScrollView实现无限循环效果

    本文实例为大家分享了Unity ScrollView实现无限循环效果的具体代码,供大家参考,具体内容如下 在Unity引擎中ScrollView组件是一个使用率比较高的组件,该组件能上下或者左右拖动的UI列表,背包.展示多个按钮等情况的时候会用到,在做排行榜类似界面时,item非常多,可能有几百个,一次创建这么多GameObject是非常卡的.为此,使用只创建可视区一共显示的个数,加上后置准备个数. 由于ScrollView有两种滚动方式,水平滚动或者垂直滚动,所以我创建了ScrollBase基

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

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

  • unity实现屏幕上写字效果

    本文实例为大家分享了unity实现屏幕上写字效果的具体代码,供大家参考,具体内容如下 先建立一个RawImage,然后再在这个图片上加个LineRenderer组件,再建个材质球,把材质球的Shader改成Particles/Additive,把材质球拖给LineRenderer组件的Materials/Element 0(不拖也可以),最后再把代码拖给空物体即可,代码的Target是RawImage,下面的代码 using System.Collections; using System.Co

随机推荐