Unity3D UGUI实现缩放循环拖动卡牌展示效果
程序员文章站
2023-12-06 14:01:16
本文实例为大家分享了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; } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Win7系统如何开启/关闭无线路由器SSID广播?
下一篇: 查看eclipse版本号的方法小结