欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity实现卡牌翻动效果

程序员文章站 2023-11-17 15:17:22
本文实例为大家分享了unity实现卡牌翻动效果展示的具体代码,供大家参考,具体内容如下 事实上这是项目需要,我改的一个代码,实际上就是利用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();
  }
 
}

效果与引用:

Unity实现卡牌翻动效果Unity实现卡牌翻动效果

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