Unity实现卡牌翻动效果
程序员文章站
2023-12-10 09:03:58
本文实例为大家分享了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(); } }
效果与引用:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。