侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Unity UI拖拽模型选择功能

技术  /  管理员 发布于 7年前   222

指定一块区域,玩家鼠标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)  {  }}

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


  • 上一条:
    unity3D实现摄像机抖动特效
    下一条:
    使用Linq注意事项避免报错的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 2024.07.09日OpenAI将终止对中国等国家和地区API服务(0个评论)
    • 2024/6/9最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(0个评论)
    • 国外服务器实现api.openai.com反代nginx配置(0个评论)
    • 2024/4/28最新免费公益节点SSR/V2ray/Shadowrocket/Clash节点分享|科学上网|免费梯子(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2017-09
    • 2018-01
    • 2018-07
    • 2018-08
    • 2018-09
    • 2018-12
    • 2019-01
    • 2019-02
    • 2019-03
    • 2019-04
    • 2019-05
    • 2019-06
    • 2019-07
    • 2019-08
    • 2019-09
    • 2019-10
    • 2019-11
    • 2019-12
    • 2020-01
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-12
    • 2024-02
    • 2024-04
    • 2024-05
    • 2024-06
    • 2025-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客