Unity将模型的世界坐标下的中心点归到模型中心

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

Unity将模型的世界坐标下的中心点归到模型中心

效果对比:
调整前:
unity设置中心点,unity知识点,unity,游戏引擎,c#
调整后:
unity设置中心点,unity知识点,unity,游戏引擎,c#

需求:由于建模时的疏忽或者网上找的一些测试模型不规范,会出现导入unity中,模型的世界坐标下的中心点与模型实际的位置差出很多。

方法一:改变模型原文件的网格位置,通过添加空父物体调整

#region 重置模型父物体和父父物体的中心点
            Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
            //获取所有MeshRenderer 包括子物体
            var mrs = transform.GetComponentsInChildren<MeshRenderer>(true);
            Vector3 center = Vector3.zero;
            for (int i = 0; i < mrs.Length; i++)
            {
                center += mrs[i].bounds.center;
                //Encapsulate函数重新计算bounds
                bounds.Encapsulate(mrs[i].bounds);
            }
            center /= mrs.Length;

            //设置父物体中心点
            GameObject obj = transform.parent.gameObject;
            transform.SetParent(obj.transform.parent);
            obj.transform.position = center;
            obj.transform.rotation = Quaternion.identity;
            transform.SetParent(obj.transform);

            //设置物体中心点
            List<Transform> list = new List<Transform>();
            for (int i = 0; i < transform.childCount; i++)
            {
                list.Add(transform.GetChild(i).transform);
                transform.GetChild(i).SetParent(obj.transform);
            }
            transform.localPosition = Vector3.zero;
            transform.localRotation = Quaternion.identity;
            for (int i = 0; i < list.Count; i++)
            {
                list[i].SetParent(transform);
            }
            #endregion

注意:物体中心点和父物体中心点的设置代码隐忍而异,看模型结构需求

方法二:通过改变模型原文件的网格位置来达到目的

 #region 重置模型的中心点 
            Vector3 position = transform.position;
            Quaternion quaternion = transform.rotation;
            Vector3 scale = transform.localScale;
            transform.position = Vector3.zero;
            transform.rotation = Quaternion.Euler(Vector3.zero);
            transform.localScale = Vector3.one;

            MeshFilter[] meshFilters = transform.GetComponentsInChildren<MeshFilter>();
            for (int i = 0; i < meshFilters.Length; i++)
            {
                MeshFilter meshFilter = meshFilters[i];
                Vector3 meshCenterPos = meshFilter.sharedMesh.bounds.center;
                Vector3 worldPos = meshFilter.transform.position;
                //模型中心和世界坐标的差值向量
                Vector3 offSet = worldPos - meshCenterPos;
                Vector3[] vectices = meshFilter.sharedMesh.vertices;
                for (int j = 0; j < vectices.Length; j++)
                {
                    vectices[j] += offSet;
                }
                meshFilter.sharedMesh.vertices = vectices;

                //重新构建mesh 
                meshFilter.sharedMesh.RecalculateBounds();
                meshFilter.sharedMesh.RecalculateNormals();
                meshFilter.sharedMesh.RecalculateTangents();
                //若最终坐标位置不对,可能由于原模型有旋转等造成,可根据实际调整坐标赋值。
                //meshFilter.transform.position = new Vector3(meshCenterPos.x, meshCenterPos.z, -meshCenterPos.y);
                meshFilter.transform.position = meshCenterPos;
            }

            transform.position = position;
            transform.rotation = quaternion;
            transform.localScale = scale;
            #endregion

注意:这里模型的位置必须Reset,这样才能保证计算准确。计算完以后,再把原位置赋值回去即可。

总结:因为需求,我们的模型都是代码生成的,所以最后我们采用了二者结合的方式。

/// <summary>
        /// 设置模型的中心点
        /// </summary>
        /// <param name="transform"></param>
        private void SetModelCenter(Transform transform)
        {
            #region 重置模型的中心点 
            Vector3 position = transform.position;
            Quaternion quaternion = transform.rotation;
            Vector3 scale = transform.localScale;
            transform.position = Vector3.zero;
            transform.rotation = Quaternion.Euler(Vector3.zero);
            transform.localScale = Vector3.one;

            MeshFilter[] meshFilters = transform.GetComponentsInChildren<MeshFilter>();
            for (int i = 0; i < meshFilters.Length; i++)
            {
                MeshFilter meshFilter = meshFilters[i];
                Vector3 meshCenterPos = meshFilter.sharedMesh.bounds.center;
                Vector3 worldPos = meshFilter.transform.position;
                //模型中心和世界坐标的差值向量
                Vector3 offSet = worldPos - meshCenterPos;
                Vector3[] vectices = meshFilter.sharedMesh.vertices;
                for (int j = 0; j < vectices.Length; j++)
                {
                    vectices[j] += offSet;
                }
                meshFilter.sharedMesh.vertices = vectices;

                //重新构建mesh 
                meshFilter.sharedMesh.RecalculateBounds();
                meshFilter.sharedMesh.RecalculateNormals();
                meshFilter.sharedMesh.RecalculateTangents();
                //若最终坐标位置不对,可能由于原模型有旋转等造成,可根据实际调整坐标赋值。
                //meshFilter.transform.position = new Vector3(meshCenterPos.x, meshCenterPos.z, -meshCenterPos.y);
                meshFilter.transform.position = meshCenterPos;
            }

            transform.position = position;
            transform.rotation = quaternion;
            transform.localScale = scale;
            #endregion

            #region 重置模型父物体和父父物体的中心点
            Bounds bounds = new Bounds(Vector3.zero, Vector3.zero);
            //获取所有MeshRenderer 包括子物体
            var mrs = transform.GetComponentsInChildren<MeshRenderer>(true);
            Vector3 center = Vector3.zero;
            for (int i = 0; i < mrs.Length; i++)
            {
                center += mrs[i].bounds.center;
                //Encapsulate函数重新计算bounds
                bounds.Encapsulate(mrs[i].bounds);
            }
            center /= mrs.Length;

            //设置父物体中心点
            GameObject obj = transform.parent.gameObject;
            transform.SetParent(obj.transform.parent);
            obj.transform.position = center;
            obj.transform.rotation = Quaternion.identity;
            transform.SetParent(obj.transform);

            //设置物体中心点
            List<Transform> list = new List<Transform>();
            for (int i = 0; i < transform.childCount; i++)
            {
                list.Add(transform.GetChild(i).transform);
                transform.GetChild(i).SetParent(obj.transform);
            }
            transform.localPosition = Vector3.zero;
            transform.localRotation = Quaternion.identity;
            for (int i = 0; i < list.Count; i++)
            {
                list[i].SetParent(transform);
            }
            #endregion
        }

参考博文:

https://blog.csdn.net/weixin_39562801/article/details/107842345文章来源地址https://www.toymoban.com/news/detail-771706.html

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

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

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

相关文章

  • 【opencv3】鼠标框选矩形并显示当前像素点坐标和矩形中心点坐标C++

    (1)用鼠标在图中框选矩形目标,然后保存框选的图片; (2)鼠标拖动过程中要求显示框的线条以及鼠标当前像素点信息(坐标和RGB值); (3)拖动完成后单独显示框取的图像,拖动完成后cout输出框中心像素点坐标。 鼠标事件: 鼠标左键按下时(event == CV_EVENT_LBUTTONUP),标

    2024年02月09日
    浏览(44)
  • 基于飞浆OCR的文本框box及坐标中心点检测JSON格式保存文本

    一、借助飞浆框出OCR识别的文本框 二、以圆圈形式标出每个框的中心点位置 三、以JSON及文本格式保存OCR识别的文本 四、以文本格式保存必要的文本信息 一、文本的坐标来自飞浆的COR识别 二、借助paddleocr的draw_ocr画出文本的外框 三、中心点由坐标的左上和右下均值得出 四、

    2024年02月03日
    浏览(33)
  • 经纬度坐标为中心点生成米距离长度半径的圆形面,含java js源码+在线绘制,代码简单零依赖

    目录 java版源码 js版源码 在线绘制预览效果 关于计算的精确度 前些时间在更新我的坐标边界查询工具的时候,需要用到经纬度坐标点的距离计算,和以坐标点为中心生成一个指定距离为半径的圆,搜了一下没有找到现成简单又合适的代码,于是把自己压箱底的代码翻出来了

    2024年02月08日
    浏览(51)
  • UE4中修改模型的中心点

    在UE4中的模型中心点一般都在模型的中点,如果是门这样的模型,我们就不能绕中心点旋转了,不然会觉得很奇怪。但是默认的静态网格体中心点都在物体中心,那我们怎么办?有两种方法: 1.我们就需要移动物体的中心点 2.在三维建模软件中移动模型中心点 下面我们就讨论

    2023年04月08日
    浏览(62)
  • 从零开始Vue项目中使用MapboxGL开发三维地图教程(四)改变鼠标style、地图置于单击feature中心、量测距离和polgon面积和中心点坐标

    总章节 从零开始Vue项目中使用MapboxGL开发三维地图教程 (一) MapboxGL介绍以及前期vue项目的搭建 (二) Mapbox地图样式 (三) 添加全屏,缩放旋转和比例控制面板以及自定义图标、标记点击弹窗、地图平移等功能 (四) 改变鼠标style、地图置于单击feature中心、量测距离和polgon面积和中

    2024年02月09日
    浏览(52)
  • Unity中如何修改精灵(Sprite)的中心点(Pivot)位置

    在Unity中,精灵(Sprite)是游戏中最常用的图形资源之一。精灵的中心点(Pivot)决定了它的旋转和缩放的中心位置。默认情况下,精灵的中心点位于其包围盒(Bounding Box)的中心。然而,在某些情况下,我们可能需要将精灵的中心点设置为不同的位置,以便更好地适应特定的需求

    2024年02月04日
    浏览(55)
  • 【赏】three.js如何确定3dtile格式的模型的中心点和缩放比例

    three.js如何确定3dtile格式的模型的中心点和缩放比例。 有多个3dtile格式的模型(tileset.json + b3dm),请问如何确定合适的比例?即在three.js中如何确定像机的位置和缩放比例? 在three.js中确定3D模型的中心点和缩放比例通常需要以下步骤: 加载3D模型。使用three.js的加载器(例如

    2024年02月08日
    浏览(52)
  • 【Unity细节】为什么UI移动了锚点,中心点和位置,运行的时候还是不在设置的位置当中

    👨‍💻个人主页 :@元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 😶‍🌫️收录于专栏 :unity细节和bug 😶‍🌫️优质专栏 ⭐【软件设计师高频考点暴击】 此时我已经将锚点设置为左上角,但是运行时它不在左上角,而是在中间 它的父对象不

    2024年02月05日
    浏览(71)
  • PCL圆柱中心轴线提取、中心点提取

    适用于 圆柱中心轴线计算,轴线的端点、中心点计算 附代码完整实现及测试代码。 相关链接: C++ PCL点云圆柱结构提取/立杆结构提取

    2024年02月14日
    浏览(51)
  • 直线围绕中心点旋转(类似时钟)

    2024年04月09日
    浏览(56)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包