Unity UI拖拽模型选择功能
程序员文章站
2023-02-20 20:11:42
指定一块区域,玩家鼠标or手指拖拽这个区域,模型会进行偏移,并用于进行人物、道具的选择
给模型定义一些属性
using system.collections;
using...
指定一块区域,玩家鼠标or手指拖拽这个区域,模型会进行偏移,并用于进行人物、道具的选择
给模型定义一些属性
using system.collections; using system.collections.generic; using unityengine; public class uimodelutil : monobehaviour { public animator animator; public int id; public int index; }
模型控制
using system.collections; using system.collections.generic; using unityengine; public class uimodelcontrol : monobehaviour { public transform modelsparent; public transform centerpos; public float interval; public bool loop; list<uimodelutil> models; bool ispressing; public uidrag dragcomp; vector3 mousepos; private void awake() { if(models == null) { int i = 0; models = new list<uimodelutil>(); foreach(uimodelutil util in modelsparent.getcomponentsinchildren<uimodelutil>()) { models.add(util); //util.index = i; vector3 pos = vector3.zero; pos.x = i * interval; util.transform.localposition = pos; i++; } } } private void start() { jumptoselect(); } private void update() { //接受拖拽事件 if (ispressing) { float x = getinputdeltax(); int dir = 0; if (x > 0) dir = 1; else if (x < 0) dir = -1; //分辨率修正 if (dir == 0) return; x = mathf.abs(x) / (screen.width) * 800f; if (x > 800f) x = 800f; //偏移 float currectx = mathf.lerp(0, interval, x / 800f) * dir; vector3 pos = modelsparent.position; pos.x += currectx; transform right = getright().transform; transform left = getleft().transform; //不循环时候设置边框 if (models.count > 2 || !loop || models.count == 1) { if (right.localposition.x + interval / 10 < -pos.x) pos.x = -(right.localposition.x + interval / 10); else if (left.localposition.x - interval / 10 > -pos.x) pos.x = -(left.localposition.x - interval / 10); //modelsparent.position = pos; } //只有两个循环的时候 else if (models.count == 2 && loop) { transform selected = getselect().transform; //当前是右边那个且向右拖拽 if (selected == right && dir < 0) { vector3 leftpos = left.localposition; leftpos.x = right.localposition.x + interval; left.localposition = leftpos; } //当前是左边那个且向左拖拽 else if (selected == left && dir > 0) { vector3 rightpos = right.localposition; rightpos.x = left.localposition.x - interval; right.localposition = rightpos; } } modelsparent.position = pos; afterselect(); } } void afterselect() { foreach(uimodelutil util in models) { float dis = getxdis(util); //设置显示 if (dis > interval) util.gameobject.setactive(false); else { //越靠近中间越前 util.gameobject.setactive(true); float t = mathf.abs(dis) / interval; float y = mathf.lerp(centerpos.position.z, modelsparent.position.z, t); vector3 pos = util.transform.position; pos.z = y; util.transform.position = pos; } } //循环时候位置修正 if (loop && models.count > 2) { transform right = getright().transform; transform left = getleft().transform; transform selected = getselect().transform; if (selected == right) { vector3 pos = right.position; pos.x += interval; left.position = pos; } else if (selected == left) { vector3 pos = left.position; pos.x -= interval; right.position = pos; } } //设置ui选中状况 dragcomp.onselected(getselect().id, getselect().index); } //通过id选中 uimodelutil getbyid(int id) { if (models == null) return null; uimodelutil target = null; foreach (uimodelutil util in models) { if (util.id == id) return util; } return target; } //获取当前选中 uimodelutil getselect() { if (models == null) return null; float min = 9999; uimodelutil target = null; foreach(uimodelutil util in models) { float dis = mathf.abs( getxdis(util)); if(dis < min) { target = util; min = dis; } } return target; } //所有模型最右边的那个 uimodelutil getright() { if (models == null) return null; float max = -9999; uimodelutil target = null; foreach(uimodelutil util in models) { float dis = util.transform.localposition.x; if(dis > max) { target = util; max = dis; } } return target; } //所有模型最左边的那个 uimodelutil getleft() { if (models == null) return null; float min = 9999; uimodelutil target = null; foreach(uimodelutil util in models) { float dis = util.transform.localposition.x; if(dis < min) { target = util; min = dis; } } return target; } //ui控件按下触发 public void onpress() { if (ispressing) return; ispressing = true; if (application.iseditor) mousepos = input.mouseposition; else mousepos = input.gettouch(0).position; if (backing != null) stopcoroutine(backing); } //ui控件释放触发 public void onrelease() { backing = startcoroutine(toselect()); ispressing = false; } coroutine backing; //释放后偏移 ienumerator toselect() { uimodelutil selected = getselect(); float dis = getxdis(selected); float time = mathf.lerp (0, 1f, mathf.abs(dis) / interval); float timer = 0; vector3 from = modelsparent.localposition; vector3 to = from; to.x = -selected.transform.localposition.x; while(timer < time) { timer += time.deltatime; float t = timer / time; vector3 pos = vector3.lerp(from, to, t); modelsparent.localposition = pos; afterselect(); yield return null; } backing = null; } //获取手指偏移量 float getinputdeltax() { vector3 pos; if (application.iseditor) pos = input.mouseposition; else pos = input.gettouch(0).position; vector3 delta = pos - mousepos; //debug.log(pos +"/"+mousepos +"/"+ delta.x); mousepos = pos; return delta.x; } //计算偏移中心位置的x轴距离 float getxdis(uimodelutil util) { return util.transform.position.x - centerpos.position.x; } // 跳转到选中的id public void jumptoselect() { int id = charactermanager.characterid; vector3 pos = modelsparent.localposition; uimodelutil selected = getbyid(id); pos.x = -selected.transform.localposition.x; modelsparent.localposition = pos; afterselect(); } }
ui接受点击事件:
using system.collections; using system.collections.generic; using unityengine; using unityengine.eventsystems; public class uidrag : monobehaviour,ipointerdownhandler, ipointeruphandler { public uimodelcontrol control; virtual public void onpointerdown(pointereventdata data) { control.onpress(); } virtual public void onpointerup(pointereventdata data) { control.onrelease(); } virtual public void onselected(int id, int index) { } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。