Unity UI拖拽模型选择

2023-11-15

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

    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity UI拖拽模型选择 的相关文章

  • Unity用Vuforia做AR实现脱卡效果

    有时在识别目标丢失后我们仍希望虚拟物体能够出现在摄像机前 或者到一个特定的位置 我们能对其进行操作 这就是脱卡功能 自带的脱卡功能应该是ExtendedTracking 允许模型在识别图丢失的时候还存在 位置不变 在丢失的时候的位置 这样也
  • Unity—UGUI

    每日一句 读数 学习 去更远的地方 才能摆脱那些你不屑一顾的圈子 目录 InputFiled输入框 例 用户名和密码 Toggle组件 案例 冷却效果 InputFiled输入框 Text Component 输入文本组件 Text输入内容
  • unity game界面按下play会不断闪烁,按下暂停键(pause)或者中止/下一步(step),game界面的画面会接连变化

    没找到答案 改了两个下午的程序 改完还是这样 后来发现是FixedUpdate Update与OnDrawGizmos的问题 OnDrawGizmos是每帧都会绘制 用FixedUpdate理所当然就那啥了 分析的时候 就突然想到是不是这俩
  • Unity中loading页加载的实现

    首先创建一个Global cs 使用单例用于存储场景的名字 便于后续脚本的调用 此脚本不必挂载在游戏物体上 using UnityEngine using System Collections public class Global Mon
  • c#获取cpu序列号

  • Unity Shader入门精要第七章 基础纹理之遮罩纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一 实践 参考 前言 遮罩纹理 mask texture 是本章要介绍的最后一种纹理 它非常有用 在很多商业游戏中 都可以见到它的身影 那么什么是遮罩呢 简单来讲 遮罩允许我们
  • Unity中按钮检测鼠标状态

    改方法主要是用于按钮检测鼠标的进入 滑出 点击 抬起 长按 长按停止 1 先将下面这个脚本挂载到需要检测鼠标状态的按钮上 using System Collections using System Collections Generic u
  • Unity与Android的Back键冲突解决

    Unity与Android的Back键冲突解决 上一篇的最后留下了两个问题 Unity视图下横屏闪退 Unity视图下Android无法响应back返回上一activity 对于第一个问题 应该是Unity横屏下视图的某些设置跟Androi
  • unity中创建询问弹出窗口

    在开发过程中进程会遇到需要弹出一个窗口询问用户是否进行的操作 今天就来制作一个这样弹出窗口 然后根据弹出窗口的选择内容不同进行不同的操作 本例中主要是为了删除一个数据 而在删除数据操作前需要得到用户的一个确认操作 这里面主要用到了Notif
  • unity后台加密时间锁

    前言 在做一些项目的时候 有些不良甲方在给完项目后会有不给尾款的情况 之前都是加一些水印啥的 感觉不是很方便 第一不美观 第二如果甲方给完尾款后还得重新打包去水印 然后又做过一个本地的时间锁 等到时间 程序直接退出 但是感觉还是不方便 有时
  • unity3d大型互动照片墙

    1 本次应客户需求 制作一个大型照片墙互动 输出分辨率为9600 4320 注 unity3d官方推荐最大分辨率为8192 3686 4 经过现场长达24小时暴力测试中途未发生问题 姑且判定可以达到正常标准 废话不多说 先上效果 unity
  • Unity保存图片到相册

    Unity保存图片到Android相册 Java 纯文本查看 复制代码 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
  • 【Unity步步升】监控与检测物体的各种方案,如:射线、碰撞、挂载等...

    在制作AR模型数值控制方案的时候遇到了检测的问题 学习过程受益匪浅 故今天为大家整理带来一篇监控与检测物体的参考方案集合 目录 一 射线检测 二 物体存在检测 三 碰撞检测 一 射线检测 单射线检测 首先完成搭建场景如下图1 1 我这里用到
  • Unity旋转以及万向锁问题

    我之前研读了一些关于unity旋转相关的博客 一直想抽个时间写个总结 但是由于实习太忙一直没有写 趁着今天请了假晚上有时间把这段时间一些学习心得写出来 Unity inspector面板中的Rotation 在unity中 想必大家最先接触
  • unity3d切换场景Application.LoadLevel(1)含义

    Application LoadLevel 1 场景ID
  • 游戏开发常见操作梳理之NPC任务系统

    多数游戏存在任务系统 接下来介绍通过NPC触发任务的游戏制作代码 using System Collections using System Collections Generic using UnityEngine
  • 游戏开发创建操作之玩家信息系统的建立

    游戏一般都需要玩家信息系统 那么我们应该如何搭建玩家信息系统 接下来我将展示一种简单的方法 完整代码如下 using System Collections using System Collections Generic using Uni
  • 游戏开发常见操作梳理之NPC药品商店系统(NGUI版)

    后续会出UGUI Json的版本 敬请期待 游戏开发中经常会出现药品商店 实际操作与武器商店类似 甚至根据实际情况可以简化设置 废话不多说 直接上代码 药品商店的源码 using System Collections using Syste
  • 游戏开发常见操作梳理之角色选择一

    进入游戏后 我们经常会进入角色选择的界面 通常是左右两个按钮可以更改角色供玩家选择 对于这种界面我们通常使用数据持久化将角色信息存储起来 接下来的笔记中 我将使用自带的数据持久化系统对其进行操作 实现角色的选择页面 后续会更新xml系列的文
  • 游戏开发常见操作系列之敌人系统的开发一(U3D)

    在开发游戏的过程中 我们常常会出现一些敌人攻击我们玩家 并且实现掉血以及死亡的现象 敌人还会源源不断地生成 这是怎么制作的呢 接下来为大家提供方法 其中使用了NGUI 后续会更新其它方法 敬请期待 使用HUDText实现扣血时显示文本 直接

随机推荐

  • oracle在线日志损坏,前在线日志文件损坏与ora-600 [4000]处理

    这次又是一台机器上面有两个实例A和B 又是由于非当前的在线日志文件的状态是处于closed状态的 裸设备 于是dba将A节点的非当前在线日志文件填加到了B节点上面去了 于是在A节点日志发生切换时 导致了当前在线日志文件损坏 一般情况下当前在
  • 前端性能优化之页面加载

    牛客在线求职答疑中心 35799 牛客在线求职答疑中心 华为oppe 联洲国际3个offer该如何选择 牛客在线求职答疑中心 35799 牛客在线求职答疑中心 华为oppe 联洲国际3个offer该如何选择 想问一下紫光同芯这家公司 他们的
  • 【计算机网络】(五)网络层之ip地址+数据封装

    1 ip地址 1 1 IP地址一些概述 Internet protocol 互联网协议 IP地址 其实就是互联网协议里使用的地址 一台电脑 一个服务器都是一台主机 IP地址是主机唯一的标识 保证主机间正常通信 一种网络编码 用来确定网络中一
  • python os 模块

    os 模块 可以通过os模块调用系统命令 获得路径 获取操作系统的类型等都是使用该模块 1 通过os 获取系统类型 os name import os print os name nt nt 代表windows posix linux gt
  • C++ set容器及其常见操作

    文章目录 前言 一 什么是set容器 二 set容器的特征 三 set容器的常见操作 四 使用步骤 1 引入头文件 2 set容器的定义 3 set的插入和删除 4 set的遍历 5 set size 总结 前言 使用集合框架不仅能提高我们
  • c++动静编译的区别

    动态编译和静态编译的区别 动态编译决定了在程序运行时才会连接库文件 需要部署的坏境安装对应库 程序体积小 静态编译在编译时就连接好库文件了 所有库文件都打包进程序了 所以体积大 不过移植性好 demo 静态编译 test h ifndef
  • 使用docker创建fdfs并使用

    1 拉取镜像 docker pull delron fastdfs 2 使用docker镜像构建tracker容器 docker run dti network host name tracker v var fdfs tracker va
  • linux执行使分区生效的命令,Linux硬盘分区生效命令partprobe

    在Linux中使用fdisk命令进行分区时 有时会遇到 WARNING Re reading the partition table failed with error 16 Device or resource busy The kern
  • nodejs知识系列:npm查询包的所有版本及安装指定版本

    说明 在添加依赖或者安装本地环境时 有时候不支持最新的安装包 需要自己指定版本号 博主最近在win7开发nestjs和angular经常遇到 解决方案 npm view 目标包名 versions json或cnpm view 目标包名 v
  • python矩阵交换两行_Python 实现交换矩阵的行示例

    Python 实现交换矩阵的行示例 如下所示 TODO r1 r2 直接修改参数矩阵 无返回值 def swapRows M r1 r2 M r1 M r2 M r2 M r1 pass 以上这篇Python 实现交换矩阵的行示例就是小编分
  • 人工智能-统计机器学习- 自适应提升算法

    监督学习 Boosting adaptive boosting 自适应提升 对于一个复杂的分类任务 可以将其分解为 若干子任务 然后将若干子任务完成方法综合 最终完成该复杂任务 我们将这若干子任务称为弱分类器 weak classifier
  • 敏捷子弹(摘自《代码之道》第二章)

    最近面试了几家公司 感觉大家对采纳Scrum流程还是挺感兴趣的 5年前 我翻译了 代码之道 这本书 其中 第二章有一篇文章谈到了敏捷方法 文章的后半部分还对Scrum做了重点介绍 作者原是微软员工 他的一些观点和建议难免会结合微软公司的实践
  • 二分查找模板

    二分查找模板 基础模板 适用于查找某个在数组中的数的位置 def searchInsert self nums List int target int gt int n len nums l 0 注意1 r n 1 注意2 while l
  • JS_socket.io简单使用

    安装socket io npm install save socket io demo目录 index js node modules package json views index html 服务端代码 index js const h
  • Solidity 合约安全,常见漏洞(第三篇)

    Solidity 合约安全 常见漏洞 第三篇 ERC20 代币问题 如果你只处理受信任的 ERC20 代币 这些问题大多不适用 然而 当与任意的或部分不受信任的 ERC20 代币交互时 就有一些需要注意的地方 ERC20 转账扣费 当与不信
  • 建模杂谈系列231 对象化-学习型对象

    说明 简单归纳一下最近的学习型对象封装 做一个基类 之后可以基于这个基类继续迭代 内容 1 关于字典的格式 Python的字典格式写起来太麻烦了 所以我定义了一个简单对象 来取代字典 字典的赋值方式 a dict a dict abc 1
  • 为什么 Linux 没有注册表?

    目录 linux无注册表机制的优势 为什么 Linux 没有注册表 linux无注册表机制的优势 linux系统有注册表吗 鸿网互联 本教程操作环境 linux7 3系统 Dell G3电脑 linux系统没有注册表 注册表 Registr
  • MySql 插入(insert)性能测试 以及优化

    http blog csdn net lgh1117 article details 8619486 测试环境 笔记本电脑 CPU I5 系统 MAC OS 10 7 内存 8G 硬盘 5400转 笔记本硬盘 MySql 版本 Oracle
  • ChatGLM(国内版的chatGPT)

    Git链接 GitHub THUDM ChatGLM 6B ChatGLM 6B 开源双语对话语言模型 An Open Bilingual Dialogue Language Model 介绍 ChatGLM 6B 是一个开源的 支持中英双
  • Unity UI拖拽模型选择

    指定一块区域 玩家鼠标or手指拖拽这个区域 模型会进行偏移 并用于进行人物 道具的选择 给模型定义一些属性 using System Collections using System Collections Generic using Un