Unity3D测量距离实现方法(一)

news2024/11/16 9:52:31

系列文章目录

unity工具


文章目录

  • 系列文章目录
  • 👉前言
  • 👉一、Unity距离测量
    • 1-1 制作预制体
    • 1-2 编写测量的脚本
  • 👉二、鼠标点击模型进行测量
  • 👉二、字体面向摄像机的方法
  • 👉二、最短距离测量方法
  • 👉三、壁纸分享
  • 👉总结


👉前言

有时候会用到测量距离的问题,所以写了一个测量的小工具,方便使用,简单记录一下
大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。
欢迎点赞评论哦.
下面就让我们进入正文吧 !


提示:以下是本篇文章正文内容,下面案例可供参考
效果展示

测量距离

👉一、Unity距离测量

1-1 制作预制体

创建一个空物体,空物体下面创建两个小球并设置一下大小,接着创建一个3D字体在空物体下面,最后在空物体上面添加LineRenderer组件
创建好的结构如下
在这里插入图片描述
st和ed是小球 tm是3d字体

1-2 编写测量的脚本

脚步挂载到刚刚创建的空物体上面即可

using UnityEngine;
using TMPro;

//距离单位
public enum UnitType
{ 
   mm = 1000,  //毫米
   cm = 100,   //厘米
   dm = 10,    //分米
   m  = 1,     //米
}

//[ExecuteInEditMode]
public class Line : MonoBehaviour
{
    public GameObject StObj, EdObj;
    TextMesh tm;
    LineRenderer line;

    [Header("实时绘制(较多会卡顿)")]
    public bool IsRt = false;
    [Header("线的粗细")]
    public float LineWidth = 0.05f;
    Material LineMat;
    [Header("线的颜色")]
    public Color LineColor;
    [Header("长度单位")]
    public UnitType unittype;

    Transform tram;

    private void Start()
    {
        LineMat = new Material(Shader.Find("Standard"));
        CreateTm();
        CreateLine();
    }

    void CreateTm()
    {
        tram = transform.Find("tm");
        if (tram != null)
            tm = tram.GetComponent<TextMesh>();
        if (tm == null)
        {
            tm = new GameObject("tm").AddComponent<TextMesh>();
            tm.color = Color.white;
            tm.fontSize = 4;
            tm.transform.SetParent(this.transform);
            //tm.GetComponent<RectTransform>().sizeDelta = new Vector2(2, 1);
            //tm.alignment = TextAlignmentOptions.Center;
        }
    }
    void CreateLine()
    {
        line = gameObject.GetComponent<LineRenderer>();
        if (line == null)
            line = gameObject.AddComponent<LineRenderer>();
        line.material = LineMat;
    }
    public void DrawLineInfo()
    {
        tm.text = (Vector3.Distance(StObj.transform.position, EdObj.transform.position) * (int)unittype).ToString("F1") + unittype;
        tm.transform.position = (StObj.transform.position + EdObj.transform.position) / 2+new Vector3(0,0.1f,0);
        line.SetPositions(new Vector3[] { StObj.transform.position, EdObj.transform.position });
        line.startWidth = LineWidth;
        line.endWidth = LineWidth;
        LineMat.color = LineColor;
    }

    void Update()
    {
        if (IsRt)
            DrawLineInfo();
    }
}

👉二、鼠标点击模型进行测量

新建一个脚本进行编写
代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//测量距离
public class RangeFinding : MonoBehaviour
{
    //总控制
    public bool isClbool;
    private Vector3 posOne, posTwo;
    //测量控制
    public bool isOpenDistance;
    private int distanceInt;   //计数控制
    public Transform prefabTransform;  //测量的预制体
    private Transform myDistanceObj;
    public Transform allCLParentTransform;  //所有预制体生成的父节点
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (isClbool)
        {
            if (Input.GetMouseButtonDown(0))
            {
                posOne = Input.mousePosition;
            }
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            //距离
            if (isOpenDistance)
            {
                if (Input.GetMouseButtonUp(0))
                {
                    posTwo = Input.mousePosition;
                    if (Physics.Raycast(ray, out hit, 1000) && posOne == posTwo)
                    {
                        if (distanceInt == 0)
                        {
                            distanceInt++;
                            //鼠标点击克隆物体
                            myDistanceObj = Instantiate(prefabTransform, allCLParentTransform);
                            // transform.TransformPoint(Prefab,hit.poit, Quaternion.identity);
                            myDistanceObj.transform.GetChild(0).position = hit.point;
                          
                        }
                        else
                        {

                            myDistanceObj.transform.GetChild(1).position = hit.point;
                            //isOpenJL = false;
                            distanceInt = 0;
                        }
                        
                    }
                }
                if (distanceInt > 0)
                {
                    if (Physics.Raycast(ray, out hit, 1000))
                    {

                        myDistanceObj.transform.GetChild(1).position = hit.point;
                    }
                }
            }
        }
        }
}

脚本随便挂载,你开心就好
在这里插入图片描述
挂载完毕运行测试即可,把两个bool值勾选上就可以进行测量了
运行结果,上面我已经放过了,就在放一下吧

测量距离

👉二、字体面向摄像机的方法

如果生成的距离字体不面向摄像机的话,需要加一下面向摄像机的方法,要不然没有感觉
代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LookAtCamera : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        transform.LookAt(Camera.main.transform);
    }
}

此代码挂载到我们一开始创建的tm上面
在这里插入图片描述

👉二、最短距离测量方法

还是用到上面的预制体,其他不用改
废话不多说了直接上代码 代码如下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 最短距离  垂直距离
/// </summary>
public class MakeBeelineController : MonoBehaviour
{
    public bool isClbool;
    public bool isOpenMDistance;
    private Vector3 posOne, posTwo;

    private int distanceInt;   //记录次数
    public Transform prefabTransform;  //测量的预制体
    private Transform myDistanceObj;
    public Transform allCLParentTransform;  //所有预制体生成的父节点
    // Start is called before the first frame update
    void Start()
    {
        
    }
    public void OpenCLLLLLL()
    {
        isClbool = true;
        isOpenMDistance = true;
    }
    public void CloseCLLLLLL()
    {
      
        isClbool = false;
        isOpenMDistance = false;
        if (allCLParentTransform.childCount == 0) return;
        if (allCLParentTransform.childCount > 0)
        {
            for (int i = 0; i < allCLParentTransform.childCount; i++)
            {
                Destroy(allCLParentTransform.GetChild(i).gameObject);
            }
        }

    }
    // Update is called once per frame
    void Update()
    {
        if (isClbool)
        {
            if (Input.GetMouseButtonDown(0))
            {
                posOne = Input.mousePosition;
            }
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit,hit1;

            //最短距离
            if (isOpenMDistance)
            {
                if (Input.GetMouseButtonUp(0))
                {
                    posTwo = Input.mousePosition;
                    if (Physics.Raycast(ray, out hit) && posOne == posTwo)
                    {
                        myDistanceObj = Instantiate(prefabTransform, allCLParentTransform);

                        myDistanceObj.transform.GetChild(0).position = hit.point;

                        Vector3 fwd = Vector3.down; // myDistanceObj.transform.GetChild(0).TransformDirection(Vector3.down);
                        if (Physics.Raycast(myDistanceObj.transform.GetChild(0).position, fwd, out hit1, 1000))
                        {
                            myDistanceObj.transform.GetChild(1).position = hit1.point;
                        }
                        else
                        {
                            Destroy(myDistanceObj.gameObject);
                        }
                    }
                }
            }

        }
    }
}

场景挂载的示例图如下
在这里插入图片描述

到此距离测量的方法已经结束了,如有其他需要或疑问,请留言评论即可,如需要其他的功能请自行修改添加扩展哦,爱你们么么哒

👉三、壁纸分享

请添加图片描述
请添加图片描述
下一篇文章分享关于面积的测量

👉总结

本次总结的就是测量距离的实现,有需要会继续添加新的
如能帮助到你,就帮忙点个赞吧,三连更好哦,谢谢
你的点赞就是对博主的支持,有问题记得留言评论哦!
不定时更新Unity开发技巧,觉得有用记得一键三连哦。么么哒

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1793499.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vs code 导出插件 导入到新电脑上

1. 在 现在的电脑上 导出插件 在vscode 上执行 code --list-extensions > extensions.txt 然后项目的目录就有了一个文件 2. 将他复制到新电脑上&#xff0c;把文件放在项目的最外层&#xff08;跟上面的目录一样&#xff09; 执行命令 Get-Content extensions.txt | ForE…

快团团有货源的供货大团长如何给单个订单发货?

快团团团长给单个订单发货的步骤如下&#xff1a; 登录快团团商家后台&#xff1a;首先&#xff0c;你需要以团长的身份登录快团团的商家后台管理系统。 进入订单管理页面&#xff1a;登录后&#xff0c;在后台导航中找到并点击“订单管理”或类似的选项&#xff0c;进入订单列…

Python脚本自动填充数据和生成文档轻松办公

一&#xff0c;自动填充数据生成word文档 代码&#xff1a; from docx import Document# 创建一个新的Word文档对象 doc Document()# 添加标题 doc.add_heading(自动填充数据和生成文档, level1)# 添加段落 doc.add_paragraph(这是一个使用Python脚本自动填充数据并生成文档的…

SpringBoot 请求响应

SpringBoot 请求响应 来源于黑马程序员JavaWeb课程&#xff0c;总结笔记 1.ApiFox Apifox快速入门教程 2.基本参数 简单参数&#xff1a;在向服务器发起请求时&#xff0c;向服务器传递的是一些普通的请求数据。 //RequestController.java import jakarta.servlet.http.Htt…

Qt for Android 申请摄像头权限

步骤 1. 添加用户权限 AndroidManifest.xml 中新增&#xff08;不添加后面申请选项时不弹窗&#xff09; 或者再Qt Creator中直接添加 2. Qt代码申请权限 Qt自己封装好了一些常用的权限申请&#xff0c; 详情Qt Assistant文档搜索 QPermission查看 #include <QPermi…

层出不穷的大模型产品如何选

目录 1.概述 2.使用体验分享 2.1.功能情况 2.2.内容生成质量 2.3.隐私安全性 2.4.小结 3.独特优势和倾向选择 4.未来发展方向 4.1.技术创新 4.2.可持续可扩展性 4.3.用户体验 4.4.应用场景 4.5.政府赋能 4.6.小结 1.概述 目前市面上的大模型AIGC产品有很多&#…

【相关概念】经济金融中的Momentum

张张张三丰de思考与总结&#xff1a; 最近做的期货价格泡沫中&#xff0c;一直在说&#xff0c;momentum&#xff0c;momentum&#xff0c;momentum&#xff0c;那么究竟什么是momentum呢&#xff1f; 目前&#xff0c;在有关期货价格泡沫的研究文献中&#xff0c;一般都是研究…

创新科技,船舶岸电电源助力环保事业

岸电电源&#xff0c;也称为岸用变频电源或电子静止式岸电电源&#xff0c;是一种特别设计制造的大功率变频电源设备。这种设备主要针对船上、岸边码头等高温、高湿、高腐蚀性、大负荷冲击等恶劣使用环境&#xff0c;能够提供稳定的电源供应。它通常用于将岸边的工业用电&#…

蓝卓热电行业解决方案

能源是人类社会发展过程中的永恒话题,热电联产作为电能和热能同时生产的能源利用形式,相较传统的火力发电具有能源利用效率高等优点,可以高效解决能源及环境问题。目前&#xff0c;世界各国都将热电联产作为更高效、更环保的能源供给体系而有效措施大力推广。 如何降本增效、减…

root账号,cmd命令行能用ssh连上服务器,但是vscode连接报错Permission denied,please try again

☆ 问题描述 但是cmd能连接上 ★ 解决方案 点击 然后add到自己的配置文件下 重新选择 这个时候就会出现刚刚添加的&#xff0c;点击选择 输入密码 然后就ok了 ✅ 总结 只能说&#xff1a;玄学&#xff01;

工业互联网基本概念及关键技术(295页PPT)

资料介绍&#xff1a; 工业互联网的核心是通过工业互联网平台把设备、生产线、工厂、供应商、产品和客户紧密地连接融合起来。这种连接能够形成跨设备、跨系统、跨厂区、跨地区的互联互通&#xff0c;从而提高效率&#xff0c;推动整个制造服务体系智能化。同时&#xff0c;工…

iLogtail 2.0 重大升级,端上支持 SPL

作者&#xff1a;太业 流式处理语言发展 早期流式处理概念&#xff1a; 20 世纪 70 年代&#xff0c;编程语言如 APL 提供了对数组的流式操作&#xff0c;这可以看作是流式处理语法的早期形式。管道&#xff08;Pipes&#xff09;概念在 UNIX 系统中的引进使得可以通过命令行将…

【机器学习】必会降维算法之:独立成分分析(ICA)

独立成分分析&#xff08;ICA&#xff09; 1、引言2、独立成分分析&#xff08;ICA&#xff09;2.0 引言2.1 定义2.2 应用场景2.3 核心原理2.4 实现方式2.5 算法公式2.6 代码示例 3、总结 1、引言 小屌丝&#xff1a;鱼哥&#xff0c;最近胡塞武装很哇塞啊。 小鱼&#xff1a;…

【面试八股总结】死锁:产生条件、预防死锁、处理死锁、避免死锁

一、什么是死锁&#xff1f; 死锁是指两个&#xff08;或多个&#xff09;线程互相等待对方数据的过程&#xff0c;死锁的产生导致程序卡死&#xff0c;不解锁程序将永远⽆法进⾏下 去 二、死锁产生条件 死锁只有同时满足以下四个条件才会发生&#xff1a;互斥条件&#xff1b…

基于飞腾 D2000 8 核+ 32G DDR+板载 6 千兆电口+ 4 千兆光口高性能网络安全主板

第一章、产品介绍 1.1 产品概述 XM-D2000GW是一款基于飞腾 D2000 8 核X100 桥片高性能网络安全主板&#xff0c;D2000 为飞腾首款支持 8 核桌面平 台处理器&#xff0c;支持双通道 DDR4-2666 内存&#xff0c;芯片内置国密 SM2/SM3/SM4/SM9 加速引擎&#xff0c;支持单精度、双…

oracle 打补丁遇到 check “CheckActiveFilesAndExecutables“ failed报错处理方法

该报错是因为打补丁的时候停止集群没有停止干净进程导致的 问题 处理方法 强制停止打补丁所在节点集群服务 查看grid和oracle相关进程是否停止干净&#xff0c;发现有未关闭的进程手动kill 处理完毕继续打补丁即可

终于搞懂了!原来vue3中template使用ref无需.value是因为这个

前言 众所周知&#xff0c;vue3的template中使用ref变量无需使用.value。还可以在事件处理器中进行赋值操作时&#xff0c;无需使用.value就可以直接修改ref变量的值&#xff0c;比如&#xff1a;<button click"msg Hello Vue3">change msg</button>。…

探索UWB模块的多功能应用——UWB技术赋能智慧生活

超宽带&#xff08;Ultra-Wideband, UWB&#xff09;技术&#xff0c;凭借其高精度、低功耗和强抗干扰能力&#xff0c;正在成为智能家居领域的一项关键技术。UWB模块的应用不仅提高了智能家居设备的性能&#xff0c;还为家庭安全、设备管理和用户体验带来了显著的改善。 UWB模…

【JS实战02】轮播图

一&#xff1a;HTML页面结构 1 整体外观 2 HTML结构以及CSS样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

【微信小程序】配置

全局配置 window 节点常用配置&#xff1a; tabbar 在小程序中分为 顶部 tabbar 和 底部 tabbar。 tabbar 最少配置两个&#xff0c;最多配置五个。当渲染顶部 rabbar 时&#xff0c;不显示 icon&#xff0c;只显示文本。 tabbar 节点配置&#xff1a; 每个 tab 项的配置&…