Unity基础——组件Transform,Mesh—filter和Mesh—Renderer详解

1. Transform 组件

功能

  Transform 组件是每个游戏对象(GameObject)都自带的基础组件,它定义了游戏对象在三维空间中的位置、旋转和缩放信息,决定了游戏对象在场景中的基本状态和空间关系。所有的游戏对象都需要通过 Transform 组件来确定其在场景中的位置和姿态。

属性

  • Position(位置)
    • 类型:Vector3
    • 描述:表示游戏对象在世界坐标系或父对象坐标系中的位置。分别对应 X、Y、Z 轴的坐标值,通过修改这些值可以精确地移动游戏对象到场景中的特定位置。

  • Rotation(旋转)
    • 类型:Quaternion(在 Inspector 面板中以欧拉角 Vector3 显示,单位为度)
    • 描述:描述游戏对象绕 X、Y、Z 轴的旋转角度。通过改变旋转值,可以让游戏对象以不同的方向呈现。

  • Scale(缩放)
    • 类型:Vector3
    • 描述:用于调整游戏对象在 X、Y、Z 轴上的大小比例。值为 1 表示原始大小,大于 1 会放大,小于 1 会缩小。
使用方法
using UnityEngine;

public class TransformExample : MonoBehaviour
{
    void Start()
    {
        // 获取当前游戏对象的 Transform 组件
        Transform myTransform = transform; 

        // 设置位置
        myTransform.position = new Vector3(1f, 2f, 3f); 

        // 设置旋转
        myTransform.rotation = Quaternion.Euler(0f, 45f, 0f); 

        // 设置缩放
        myTransform.localScale = new Vector3(2f, 2f, 2f); 
    }
}


2. Mesh Filter 组件

功能

  Mesh Filter 组件主要用于指定游戏对象所使用的网格(Mesh)数据。网格数据定义了游戏对象的几何形状,包括顶点、三角形、法线等信息。简单来说,它就像是一个 “形状模板”,告诉 Unity 这个游戏对象应该是什么样子的。

属性
  • Mesh
    • 类型:Mesh
    • 描述:这是 Mesh Filter 组件的核心属性,用于指定游戏对象所使用的网格。你可以将一个预制好的网格资源赋值给它,这样游戏对象就会呈现出该网格所定义的形状。

使用方法
using UnityEngine;

public class MeshFilterExample : MonoBehaviour
{
    public Mesh customMesh;

    void Start()
    {
        // 获取 Mesh Filter 组件
        MeshFilter meshFilter = GetComponent<MeshFilter>();

        // 检查组件是否存在
        if (meshFilter != null)
        {
            // 为 Mesh Filter 组件指定网格
            meshFilter.mesh = customMesh;
        }
    }
}


3. Mesh Renderer 组件

功能

  Mesh Renderer 组件的主要功能是将 Mesh Filter 提供的网格数据渲染到屏幕上。它负责处理光照、材质、阴影等渲染相关的设置,让游戏对象能够在场景中以可视化的形式呈现出来。可以把它看作是一个 “画家”,根据网格形状和材质信息将游戏对象绘制到屏幕上。

属性

Materials(材质)

  • Element 0:表示材质元素列表中的第一个元素。
  • Default-Material:当前选择的默认材质,点击旁边的圆形图标可以打开材质选择窗口,“+” 和 “-” 按钮用于添加或删除材质元素。

Lighting(光照)

  • Cast Shadows:设置对象是否投射阴影,当前选项为 “On”,即开启投射阴影。
  • Receive Shadows:勾选表示对象可以接收其他对象投射的阴影。
  • Contribute Global :关于全局光照贡献的设置,用于控制对象对全局光照的影响。
  • Receive Global Illumi:当前选择为 “Light Probes”,意味着对象通过光照探头接收全局光照。

Probes(探头)

  • Light Probes:设置为 “Blend Probes”,表示使用混合光照探头来计算对象的光照效果
  • Reflection Probes:设置为 “Blend Probes”,即使用混合反射探头来处理对象的反射效果
  • Anchor Override:当前设置为 “None (Transform)”,可以指定一个变换对象来覆盖探头的锚点位置

Additional Settings(额外设置)

  • Motion Vectors:设置为 “Per Object Motion”,用于控制对象运动矢量的计算方式,有助于在动画或移动对象时实现更准确的渲染效果。
  • Dynamic Occlusion:勾选表示启用动态遮挡功能,可提高场景的渲染效率和真实性。

    使用方法
    using UnityEngine;
    
    public class MeshRendererExample : MonoBehaviour
    {
        public Material customMaterial;
    
        void Start()
        {
            // 获取 Mesh Renderer 组件
            MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
    
            // 检查组件是否存在
            if (meshRenderer != null)
            {
                // 设置材质
                meshRenderer.material = customMaterial;
    
                // 启用投射阴影
                meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On;
    
                // 启用接收阴影
                meshRenderer.receiveShadows = true;
            }
        }
    }
    

     


    4.综合使用示例

         以下是一个简单的示例,展示如何综合使用这三个组件创建一个具有特定位置、旋转、缩放,并且使用自定义网格和材质的游戏对象:

    using UnityEngine;
    
    public class CombinedExample : MonoBehaviour
    {
        public Mesh customMesh;
        public Material customMaterial;
    
        void Start()
        {
            // 设置 Transform 组件
            transform.position = new Vector3(0f, 0f, 0f);
            transform.rotation = Quaternion.Euler(0f, 45f, 0f);
            transform.localScale = new Vector3(2f, 2f, 2f);
    
            // 设置 Mesh Filter 组件
            MeshFilter meshFilter = GetComponent<MeshFilter>();
            if (meshFilter != null)
            {
                meshFilter.mesh = customMesh;
            }
    
            // 设置 Mesh Renderer 组件
            MeshRenderer meshRenderer = GetComponent<MeshRenderer>();
            if (meshRenderer != null)
            {
                meshRenderer.material = customMaterial;
            }
        }
    }
    

            在这个示例中,我们首先设置了游戏对象的 Transform 组件,确定其位置、旋转和缩放。然后,通过 Mesh Filter 组件指定了自定义的网格,最后使用 Mesh Renderer 组件为游戏对象应用了自定义的材质。这样,游戏对象就会以我们期望的形状和外观出现在场景中。


    5.结语

            综上所述,Transform、Mesh Filter 和 Mesh Renderer 组件在 Unity 2023 开发中扮演着举足轻重的角色。Transform 组件为游戏对象搭建了空间框架,让物体能够在场景中精准定位和灵活变换姿态;Mesh Filter 组件为物体赋予了具体的形状,使其具有了独特的几何特征;Mesh Renderer 组件则为物体增添了绚丽的外观,使其在游戏世界中栩栩如生。通过合理运用这些组件的属性和功能,开发者能够创建出丰富多彩、形态各异的游戏物体,构建出引人入胜的游戏场景。

    <think>首先,用户的问题是关于在Unity中使用脚本获取Mesh的长宽高数据。具体来说,他们想知道如何计算3D模型的边界尺寸。 从系统级指令中,我需要: - 所有行内数学表达式使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,例如[^1]。 - 结构清晰,帮助用户逐步解决问题。 - 回答真实可靠,参考提供的引用。 提供的引用: - [^1]: Mesh概念:MeshUnity中的一个数据结构,称为网格。它由点、边三角面构成。 - [^2]: Unity Mesh 生成图形(一),展示了顶点顶点下标的重要性。 - [^3]: unity Mesh绘制基础3D立体图形,包括添加顶点来创建形状。 用户的问题:在Unity中获取Mesh的边界尺寸,即长宽高计算。 关键点: - 在Unity中,Mesh的边界可以通过其包围盒(Bounding Box)来获取。 - 包围盒是一个轴对齐的边界框(AABB - Axis Aligned Bounding Box),它定义了Mesh在3D空间中的最小最大点。 - 从这些点,我们可以计算长(x轴方向)、宽(y轴方向)、高(z轴方向)。 步骤: 1. 获取Mesh的包围盒。 2. 从包围盒中提取最小点最大点。 3. 计算尺寸:长 = max.x - min.x,宽 = max.y - min.y,高 = max.z - min.z。 在Unity中,Mesh类有一个属性mesh.bounds,它返回一个Bounds结构体。Bounds结构体包含min、max、size等属性。 所以,在脚本中: - 使用MeshFilter组件获取Mesh。 - 然后访问mesh.bounds.size,这将给出一个Vector3表示尺寸:x是宽,y是高,z是长(取决于坐标系)。 - Unity的坐标系:x是左右,y是上下,z是前后。所以: - 宽:size.x(左右方向) - 高:size.y(上下方向) - 长:size.z(前后方向) 尺寸计算: - 尺寸 = max - min 在每个轴上。 在回答中,我需要结构清晰: - 解释概念。 - 提供代码示例。 - 确保代码正确。 代码示例: - 使用C#脚本。 - 假设有一个GameObject带有MeshFilter。 - 获取MeshFilter的sharedMeshmesh属性。 - 然后访问bounds.size。 例如: ```csharp using UnityEngine; public class GetMeshSize : MonoBehaviour { void Start() { MeshFilter meshFilter = GetComponent<MeshFilter>(); if (meshFilter != null) { Mesh mesh = meshFilter.mesh; Vector3 size = mesh.bounds.size; Debug.Log("Width (x): " + size.x + ", Height (y): " + size.y + ", Depth (z): " + size.z); } } } ``` 注意: - mesh.bounds是局部空间的包围盒,不是世界空间。所以它不考虑对象的缩放、旋转或位置。用户可能需要考虑变换。 - 如果需要世界空间的尺寸,需要应用对象的变换矩阵。 但用户问题中说“获取Mesh的长宽高数据”,可能指的是模型本身的尺寸,而不是在场景中的尺寸。所以局部空间可能足够。但为了完整,我可以提到这一点。 引用相关概念: - 从引用[^1],Mesh由顶点等构成,包围盒基于这些顶点。 - 引用[^2][^3]提到顶点如何创建Mesh,这些是基础。 生成相关问题: - 在回答后,添加相关问题部分。 回答结构: 1. 介绍概念:解释Mesh包围盒。 2. 步骤:如何获取尺寸。 3. 代码示例。 4. 注意事项。 5. 相关问题。 使用中文: - 整个回答用中文。 数学表达式: - 尺寸计算:$ \text{size}_x = \text{max}_x - \text{min}_x $ 等,作为行内表达式。 例如:尺寸在x轴方向为 $ \Delta x = x_{\text{max}} - x_{\text{min}} $。 在独立公式中,如果需要,但这里可能不需要独立公式,因为计算简单。 现在,构建回答。</think>在Unity中,获取Mesh的边界尺寸(长、宽、高)是通过计算Mesh的轴对齐包围盒(AABB - Axis Aligned Bounding Box)来实现的。包围盒基于Mesh的顶点数据,定义了模型在局部空间中的最小最大坐标点。从这些点,我们可以直接计算出尺寸: - **长**(通常对应z轴方向):$ \Delta z = z_{\text{max}} - z_{\text{min}} $ - **宽**(通常对应x轴方向):$ \Delta x = x_{\text{max}} - x_{\text{min}} $ - **高**(通常对应y轴方向):$ \Delta y = y_{\text{max}} - y_{\text{min}} $ UnityMesh数据结构存储了顶点信息(如位置、法线等),而`Bounds`结构体提供了便捷的属性来获取这些值[^1]。以下我将逐步说明实现方法,确保代码真实可靠。 ### 步骤详解 1. **获取Mesh组件**: 在Unity中,Mesh数据通常通过`MeshFilter`组件访问。如果对象是3D模型(如导入的FBX文件),它会自带此组件。 2. **提取包围盒(Bounds)**: - `Mesh.bounds`属性返回一个`Bounds`对象,表示Mesh在局部空间的包围盒。 - `Bounds`包含: - `min`:包围盒最小角点(Vector3)。 - `max`:包围盒最大角点(Vector3)。 - `size`:直接返回尺寸(Vector3),其中: - `size.x` = 宽(x轴方向) - `size.y` = 高(y轴方向) - `size.z` = 长(z轴方向) 3. **考虑坐标轴方向**: Unity使用右手坐标系: - x轴:左右方向(宽) - y轴:上下方向(高) - z轴:前后方向(长) 尺寸计算基于局部空间,不受对象旋转或位置影响(但受缩放影响)。如果需要世界空间尺寸,需额外处理变换矩阵。 ### 完整代码示例 以下C#脚本可附加到带有MeshFilter的GameObject上(如一个3D模型)。运行后,在控制台输出Mesh的尺寸: ```csharp using UnityEngine; public class MeshSizeCalculator : MonoBehaviour { void Start() { // 获取MeshFilter组件 MeshFilter meshFilter = GetComponent<MeshFilter>(); if (meshFilter == null) { Debug.LogError("未找到MeshFilter组件!请确保对象有MeshRenderer或SkinnedMeshRenderer。"); return; } // 获取Mesh对象(使用sharedMesh以避免运行时修改原网格) Mesh mesh = meshFilter.sharedMesh; if (mesh == null) { Debug.LogError("Mesh数据为空!"); return; } // 提取包围盒尺寸 Bounds bounds = mesh.bounds; Vector3 size = bounds.size; // size直接给出Vector3(宽, 高, 长) // 输出结果 Debug.Log($"Mesh尺寸 - 宽(x): {size.x}, 高(y): {size.y}, 长(z): {size.z}"); Debug.Log($"包围盒最小点: {bounds.min}, 最大点: {bounds.max}"); } } ``` ### 注意事项 - **局部空间 vs 世界空间**: 上述代码返回局部空间尺寸。如果对象有缩放(例如`transform.localScale`),尺寸会自动乘以缩放因子。如果需要纯模型尺寸(忽略缩放),可在计算前重置缩放: ```csharp Vector3 originalScale = transform.localScale; transform.localScale = Vector3.one; // 临时重置缩放 // 获取mesh.bounds.size transform.localScale = originalScale; // 恢复缩放 ``` - **动态Mesh**: 对于运行时修改的Mesh(如程序生成模型),确保在Mesh更新后调用此脚本,否则bounds可能未更新。 - **性能优化**: `mesh.bounds`计算基于顶点数据,复杂度为$O(1)$(Unity预计算并缓存了结果),适合实时使用[^2]。 - **引用说明**: Mesh的边界计算依赖于顶点集合,这些顶点定义了三角面结构,是3D模型的基础[^1][^3]。 ###
    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值