当前位置: 首页 > article >正文

Unity中的屏幕坐标系

获得视口宽高

拖动视口会改变屏幕宽高数值
在这里插入图片描述

MousePosition

屏幕坐标系的原点在左下角,MousePosition返回Z为0也就是纵深为0的Vector3

但是如果鼠标超出屏幕范围不会做限制,所以可能出现负数或者大于屏幕宽高的情况,做鼠标拖拽物体时需要注意是否需要跟随超出屏幕
在这里插入图片描述
下面这个写法是不对的,获得鼠标的屏幕位置纵深将一直为0,屏幕坐标转世界坐标其实是根据距离摄像机的平面确定的(z轴),所以需要先确定z轴后转世界坐标系

GetMouseWorldPosition = Camera.main.ScreenToWorldPoint(GetMousePosition);

利用射线检测物体转屏幕坐标

不会出现超出屏幕坐标系的情况

if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit))
{
    GetObjectPosition = Camera.main.WorldToScreenPoint(hit.point);
}

获得带纵深的屏幕坐标系,xy值为根据屏幕大小决定,z为距离摄像机的位置与本身的世界坐标系z无关
在这里插入图片描述

UI坐标

Canvas的世界坐标z值是距离摄像机的距离,那么子物体的世界坐标z值也是与摄像机的距离
在这里插入图片描述

实现拖曳UI

屏幕坐标XY是根据屏幕宽高决定,Z是相对摄像机的距离,将屏幕坐标看成一个个屏幕即可
世界坐标是根据世界原点确定,与屏幕坐标的Z值参考不一样

using UnityEngine;
using UnityEngine.EventSystems;

[RequireComponent(typeof(EventTrigger))]
public class DragUI : MonoBehaviour
{
    private EventTrigger m_eventTrigger;
    private RectTransform m_rectTransform;
    
    private Vector3 m_targetPosition;
    private Vector3 m_offsetPosition;
    void Start()
    {
        m_eventTrigger = GetComponent<EventTrigger>();
        m_rectTransform = GetComponent<RectTransform>();
        
        EventTrigger.Entry onDragEntry = new EventTrigger.Entry();
        onDragEntry.eventID = EventTriggerType.Drag;
        onDragEntry.callback.AddListener((data) => { OnDrag(); });
        
        EventTrigger.Entry enterDragEntry = new EventTrigger.Entry();
        enterDragEntry.eventID = EventTriggerType.BeginDrag;
        enterDragEntry.callback.AddListener((data) => { EnterDrag(); });
        
        m_eventTrigger.triggers.Add(onDragEntry);
        m_eventTrigger.triggers.Add(enterDragEntry);
    }

    private void EnterDrag()
    {
        m_offsetPosition = GetScreenMousePosition() - m_rectTransform.transform.position;
    }
    
    // 拖拽时移动UI
    private void OnDrag()
    {
        // 屏幕坐标转世界坐标
        m_targetPosition = GetScreenMousePosition();
        m_rectTransform.transform.position = m_targetPosition - m_offsetPosition;
    }
    
    // 获得鼠标世界坐标
    private Vector3 GetScreenMousePosition()
    {
        // 与摄像机的距离
        float distanceCamera = m_rectTransform.transform.position.z;
        // 鼠标位置(确定了平面的Z)
        Vector3 screenMousePos = Input.mousePosition + new Vector3(0f, 0f, distanceCamera);
        // 屏幕坐标转世界坐标
        Vector3 worldMousePos = Camera.main.ScreenToWorldPoint(screenMousePos);
        Debug.Log(worldMousePos);
        return worldMousePos;
    }
}


http://www.kler.cn/a/377422.html

相关文章:

  • 光伏无人机踏勘,照亮光伏未来!
  • 【大数据学习 | kafka高级部分】kafka的快速读写
  • 【Java Web】搭建Web环境以及初识JSP Tomcat
  • qt QStandardItem详解
  • 【算法】Floyd多源最短路径算法
  • 掌握PyQt5图形界面化工具及绑定爬虫程序
  • 【华为HCIP实战课程二十六】中间到中间系统协议IS-IS配置默认路由及IS-IS数据库,网络工程师
  • 动态规划——两个数组的dp问题
  • 2024.11.3笔试记录——学习
  • 15分钟学 Go 第 29 天:流程控制 - select语句
  • 探索NetCat:网络流量监测与数据传输的利器
  • Yelp 数据集进行用户画像, 使用聚类做推荐
  • LangChain学习之路
  • 插入/归并
  • 海风里的青春:海滨学院班级回忆录开发
  • 沈阳乐晟睿浩科技有限公司抖音小店运营创新
  • 如何在忘记密码的情况下解锁 iPhone? 6 种方法分享
  • Nat Med病理AI系列|DEPLOY模型:从病理切片图像预测中枢神经系统肿瘤甲基化状态|顶刊精析·24-11-03
  • 关闭kafka在控制台打印的日志
  • Oracle 第20章:数据库调优
  • Python基于TensorFlow实现双向长短时记忆循环神经网络加注意力机制回归模型(BiLSTM-Attention回归算法)项目实战
  • 信息技术(information Technology)
  • 安卓设备adb执行AT指令控制电话卡
  • 前端如何优化页面中的大量任务
  • vue2中的v-bind相当于原生js的什么
  • 3.1 大数据时代