Unity实现在3D模型标记

这篇具有很好参考价值的文章主要介绍了Unity实现在3D模型标记。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Canvas 模式是UI与3D混合模式(Render model=Screen space-Camera)

实现在3D模型标记,旋转跟随是UI不在3D物体下

Unity实现在3D模型标记,Unity奇奇怪怪的项目要求,unity,3d,游戏引擎

代码:文章来源地址https://www.toymoban.com/news/detail-622096.html

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ClickHandler : MonoBehaviour
{
    public Transform object3D; // 总体模型
    public GameObject imgUIPrefab;
    public Canvas canvas;
    public float fadeSpeed = 2.0f; // 淡入淡出的速度
    private bool isRotating = false;
    private GameObject clickedObject;
    private Vector3 lastMousePosition;
    private Vector3 delta;
    private Dictionary<GameObject, GameObject> generatedUIs = new Dictionary<GameObject, GameObject>();

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            lastMousePosition = Input.mousePosition;
            isRotating = true;
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;

            if (Physics.Raycast(ray, out hit))
            {
                clickedObject = hit.collider.gameObject;
                // 检查是否为小模型
                if (clickedObject.CompareTag("Model"))
                {
                    isRotating = false;
                    if (!HasGeneratedUI(clickedObject.name))
                    {
                        // 创建UI
                        GameObject imgUI = CreateUIForModel(clickedObject);
                        if (imgUI != null)
                        {
                            // 添加到字典中
                            generatedUIs.Add(imgUI, clickedObject);
                        }
                    }
                }
            }
            UpdateImgUIPosition();
        }

        if (Input.GetMouseButtonUp(0))
        {
            isRotating = false;
        }

        if (isRotating)
        {
            delta = Input.mousePosition - lastMousePosition;
            float rotationSpeed = 0.5f;
            object3D.Rotate(Vector3.up, delta.x * -rotationSpeed, Space.World);
            UpdateImgUIPosition();
        }

        lastMousePosition = Input.mousePosition;
    }

    private GameObject CreateUIForModel(GameObject model)
    {
        // 获取被点击物体的中心点位置
        Vector3 modelCenter = model.transform.position;

        // 将模型的世界坐标转换为屏幕坐标
        Vector3 screenPoint = Camera.main.WorldToScreenPoint(modelCenter);

        // 将屏幕坐标转换为Canvas内的局部坐标
        RectTransform canvasRect = canvas.GetComponent<RectTransform>();
        Vector2 canvasLocalPoint;
        RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, screenPoint, Camera.main, out canvasLocalPoint);

        // 设置预制体的位置为Canvas内的局部坐标,将Z轴位置设置为-150
        Vector3 prefabPosition = new Vector3(canvasLocalPoint.x, canvasLocalPoint.y,-150f);

        // 实例化Img UI预制件,并设置其位置为转换后的局部坐标
        GameObject imgUI = Instantiate(imgUIPrefab, prefabPosition, Quaternion.identity);
        imgUI.name = model.name; // 生成UI名字为3D模型名字
        imgUI.transform.SetParent(canvas.transform, false); // 设置Img UI的父对象为Canvas,确保其显示在屏幕上

        return imgUI;
    }

    private void UpdateImgUIPosition()
    {
        foreach (var uiEntry in generatedUIs)
        {
            GameObject ui = uiEntry.Key;
            GameObject matchedModel = uiEntry.Value;

            bool isOccluded = IsObjectOccluded(matchedModel);


            // ui.SetActive(!isOccluded);  // 如果模型被遮挡,则隐藏UI;否则显示UI

            // 如果模型被遮挡,则UI淡出 否则淡入
            Image uiImage = ui.GetComponent<Image>();
            Color color = uiImage.color;
            float targetAlpha = isOccluded ? 0.0f : 1.0f;
            color.a = Mathf.MoveTowards(color.a, targetAlpha, Time.deltaTime * fadeSpeed);
            uiImage.color = color;

            if (!isOccluded)
            {
                // 获取匹配模型的中心点位置
                Vector3 modelCenter = matchedModel.transform.position;

                // 将模型的世界坐标转换为屏幕坐标
                Vector3 screenPoint = Camera.main.WorldToScreenPoint(modelCenter);

                // 将屏幕坐标转换为Canvas内的局部坐标
                RectTransform canvasRect = canvas.GetComponent<RectTransform>();
                Vector2 canvasLocalPoint;
                RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, screenPoint, Camera.main, out canvasLocalPoint);
                Vector3 prefabPosition = new Vector3(canvasLocalPoint.x, canvasLocalPoint.y, -150f);

                // 更新UI的位置
                ui.GetComponent<RectTransform>().anchoredPosition = prefabPosition;
            }
        }
    }

    private bool HasGeneratedUI(string name)
    {
        foreach (var ui in generatedUIs.Keys)
        {
            if (ui.name == name)
            {
                return true;
            }
        }
        return false;
    }

    private bool IsObjectOccluded(GameObject obj)
    {
        // 获取摄像机到物体的方向
        Vector3 directionToTarget = obj.transform.position - Camera.main.transform.position;

        // 发射射线
        Ray ray = new Ray(Camera.main.transform.position, directionToTarget);
        RaycastHit hit;

        // 射线检测是否有其他碰撞器位于射线路径上
        if (Physics.Raycast(ray, out hit, directionToTarget.magnitude))
        {
            // 如果射线击中的物体不是目标物体,则表示目标物体被遮挡
            if (hit.collider.gameObject != obj)
            {
                return true;
            }
        }

        return false;
    }
}

到了这里,关于Unity实现在3D模型标记的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity】模型文件格式、常见3D模型格式

    Unity 支持多种标准和专有模型文件格式。Unity 内部使用 .fbx 文件格式作为其导入链。最佳做法尽可能使用 .fbx 文件格式,并且不应在生产中使用专有文件格式。 标准文件格式 Unity 可读取以下标准 3D 文件格式: .fbx .dae (Collada) .dxf .obj 这些文件格式受到广泛支持。这些类型的文

    2024年01月17日
    浏览(45)
  • 【Unity3D】使用 FBX 格式的外部模型 ( 向 Unity 中添加 FBX 模型 | 向 Scene 场景中添加 FBX 模型 | 3D 物体渲染 | 3D 物体材质设置 )

    Unity 中使用的 3D 模型格式为 FBX , 使用如下建模软件 可制作该类型模型 : 3Dmax Maya ZBrush Cinema4D Blender 建模完成后 , 将 3D 模型导出为 FBX ( .fbx ) 格式 即可在 Unity 中使用 ; 在 Project 文件窗口 中的 Asstes 目录 下 , 创建一个模型目录 Models , 将 模型文件直接从文件系统中拖到该目录中

    2023年04月15日
    浏览(79)
  • Unity3D:2D/3D 项目

    推荐:将 NSDT场景编辑器 加入你的3D工具链 3D工具集: NSDT简石数字孪生 无论是创建 2D 还是 3D 游戏,Unity 都很拿手。在 Unity 中创建新项目时,可以选择以 2D 或 3D 模式启动。您可能已经知道要构建什么,但有一些细微的要点可能会影响选择的模式。 选择是以 2D 还是 3D 模式启

    2024年02月07日
    浏览(57)
  • 【Unity】实用功能开发(一)实现在UI中用RawImage实时展示3D模型(背景透明,并通过UI防止3D场景遮挡)并可以通过分层完成:游戏中的人物状态展示界面,小地图,人物实时头像状态等功能

    有时由于项目效果需要,部分功能的实现受到阻碍,这里收集一些已实现的思路和方法,每次会记录大致需求和遇到的问题,如果有更好的想法,欢迎评论区讨论!!! 目录 功能描述: 需求描述: 实现步骤: ①为需要展示的内容区分层级: ②在场景中添加一个摄像机,并

    2024年02月04日
    浏览(45)
  • UNITY普通3D项目转换成URP项目

    注意:要确认 UniversalRP 对应的版本支持 目前此插件在2019和2020.2版本上已经得到认证 1.查看素材或询问素材支持的Unity版本 2.查看或询问素材是否支持 UniversalRP 插件 3.查看或询问素材支持的URP Unity版本 4.安装好 UniversalRP 并创建通用渲染管线 1.首先要确认模型材质支持 URP ,然

    2023年04月14日
    浏览(32)
  • Unity3D模型 | SolidWorks建模导入Unity

    本篇主要作为个人经验记录,因项目需要将SW的模型导入Unity中使用,但SW中建模为实体而Unity多为面,以及在Unity支持的模型文件格式文档中并不支持SW的文件格式。 所以需要先将模型导入3DMax中由其转换为.FBX或.3ds文件,其中二者的区别为FBX文件可以对源模型改动并同步至U

    2023年04月26日
    浏览(57)
  • IOS使用Unity容器动态加载3D模型

    项目背景 我们的APP是一个数字藏品平台,里面的很多藏品需要展示3D模型,3D模型里面可能会包含场景,动画,交互。而对应3D场景来说,考虑到要同时支持iOS端,安卓端,Unity是个天然的优秀方案。 对于Unity容器来说,需要满足如下的功能: 1.在APP启动时,需要满足动态下载

    2024年03月18日
    浏览(41)
  • Unity中从3D模型资产中批量提取材质

    如何使用 只需在“项目”窗口中创建一个名为“编辑器”的文件夹,然后在其中添加此脚本即可。然后,打开Window-Batch Extract Materials,配置参数并点击“ Extract! ”。 在Unity 2019.1+上,可以将默认材质重映射条件配置为自动检测模型资源中嵌入的重复材质并为它们提取单个材

    2024年02月04日
    浏览(47)
  • Unity 3D模型展示之webGL平台展现

    在之前的项目基础上我们已经打包后在PC端进行展示了。这篇文章主要介绍在切换到webGL上时效果展示不出来需要进行调整,特此记录一下。 1.平台切换 选择WebGL平台切换,没有的可以进行安装,安装之后关闭IDE重新启动。选择WebGL切换,参数参照以下设置即可。 2.构建WebGL项

    2024年02月01日
    浏览(32)
  • 【Unity美术】Unity工程师对3D模型需要达到的了解【二】

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity基础实战 模型导入规范文档入口, .坐标轴规范: 人物面朝向为Z轴正方向,Y轴正方向为头顶方向,X轴正方向为人物右侧 一般式用

    2024年02月03日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包