当前位置: 移动技术网 > IT编程>开发语言>c# > Unity实现卡牌翻动效果

Unity实现卡牌翻动效果

2019年07月18日  | 移动技术网IT编程  | 我要评论

本文实例为大家分享了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();
  }
 
}

效果与引用:

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网