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粒子特效附上贴图后播放动画

    转自 http jingyan baidu com article f96699bbb1a0d6894f3c1b77 html 参考 http www unitymanual com thread 2993 1 1 html dsign a
  • Unity 资源加载卸载过程

    什么时候才是UnusedAssets 看一个例子 Object obj Resources Load MyPrefab GameObject instance Instantiate obj as GameObject Destroy in
  • Unity单元测试流程

    文章目录 环境 流程 1 创建一个存放 单元测试程序集 的目录 2 打开 Test Runner 窗口 3 选择单元测试模式 4 创建单元测试程序集 5 创建测试脚本 6 运行测试 环境 Unity 2020 3 3f1 流程 1 创建一个
  • Unity 安卓打包

    Unity打包的方式有很多种 自动打包和手动打包 今天小弟就鼓捣鼓捣unity手动打包 如果想动态打包的话 可以去看其他大佬的帖帖哈 unity打包先配置环境 下载unity的时候可以顺道把unity的安卓包下载下来 如果忘了也没事 可以从
  • Unity动画系统详解

    目录 动画编辑器 编辑器面板 动画复用 前言 人形重定向动画 Humanoid 通用动画 Generic 旧版本动画 Legacy 动画控制器 系统状态 切换条件 状态机脚本 IK动画 反向动力学 BlendTree 混合树 Animato
  • Unity中实现倒计时的几种方式

    1 Time time using UnityEngine public class TimeTest MonoBehaviour public float secound 10 void Update Timing private flo
  • Unity3d 插件 系列——DoTweenPro介绍(图文详细+案例)

    Unity3d 插件 系列 DoTweenPro介绍 图文详细 案例 前言 一 DoTweenPro简介 二 DoTweenPro安装 三 DoTweenPro主要组件 1 DoTweenAnimation 2 DoTweenPath 3
  • unity中创建询问弹出窗口

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

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

    VLC for unity 插件如何使用 先去下载一个VLC播放器 安装完成后 然后导入插件链接https download csdn net my 这个插件我的另一个上传资源里有 或者到商店去下载 这个插件链接下载完是一个txt文档 里面
  • 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 我这里用到
  • unity3d 自定义的图片无法放入source image中

    须将图片的texture type改为 sprite
  • 【原神游戏开发日志1】缘起

    原神游戏开发日志1 缘起 版权声明 本文为 优梦创客 原创文章 您可以自由转载 但必须加入完整的版权声明 文章内容不得删减 修改 演绎 相关学习资源见文末 大家好 最近看到原神在TGA上频频获奖 作为一个14年经验的游戏开发行业的老兵 我就
  • Unity中URP下的指数雾

    文章目录 前言 一 指数雾 雾效因子 1 FOG EXP 2 FOG EXP2 二 MixFog 1 ComputeFogIntensity 雾效强度计算 2 lerp fogColor fragColor fogIntensity 雾效颜
  • 游戏开发创建操作之玩家信息系统的建立

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

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

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

    接下来一些笔记会对于一些大大小小的实践操作进行记录 希望对你有所帮助 在游戏中 我们经常会遇到一些按动任意键触发的操作 接下来展示核心代码 以下是对于Unity中的操作 使用的UI是NGUI 对于核心操作没有影响 你可以自己置换 void

随机推荐

  • 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