版本:Unity 6 (6000.0)
语言简体中文
  • C#

物理学.BakeMesh

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有的意见,但我们会阅读来自我们用户的每条建议更改记录,然后在适用的情况下更新。

关闭

提交失败

由于某些原因,无法提交您的建议更改记录。请在几分钟内<a>重试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

声明

public static void BakeMesh(int meshID, bool convex);

参数

meshID 用于烘焙碰撞数据的网格的实例化 ID。
convex 一个标志,指示是否烘焙凸几何。

说明

准备用于 网格碰撞器 的网格,并使用默认烹饪选项。


声明

public static void BakeMesh(int meshID, bool convex, 网格碰撞器烹饪选项 cookingOptions);

参数

meshID 用于烘焙碰撞数据的网格的实例化 ID。
convex 一个标志,指示是否烘焙凸几何。
cookingOptions 烘焙网格时使用的烹饪选项。

说明

准备用于 网格碰撞器 的网格。

为了让网格可与 网格碰撞器 一起使用,物理系统必须先准备它,方法是创建空间搜索加速结构。此过程称为烘焙。

通常,网格碰撞器组件在用户实例化它时或在用户使用 sharedMesh 属性向其设置新网格时需要烘焙的网格。烘焙是一个资源密集型操作,因此您可能需要在时机合适时(例如在应用程序资源密集程度较低的部分)运行它,或者在所有可用内核间分散负载(如果有多个网格需要烘焙的话)。话虽如此,此函数的目的是预先烘焙网格以供以后使用,以免需要再次烘焙。

网格实例存储烘焙的网格。

烘焙过程需要访问网格几何。如果用户在播放器中调用 BakeMesh 方法,则 BakeMesh 方法需要启用网格的读写属性。但是,在编辑器中使用 BakeMesh 方法不需要任何额外的设置,因为几何始终在编辑器中可用。

当且仅当满足以下所有条件时,网格碰撞器组件才会重复使用烘焙网格

  • 网格碰撞器的 cookingOptions 与烘焙期间指定的 cookingOptions 完全相同,
  • 网格碰撞器的变换允许共享网格 (*),
  • 自上次烘焙以来网格几何形状未发生改变。

在此上下文中,网格碰撞器的变换允许共享网格,如果

  • 其缩放不是负的且没有扭曲,或者
  • 其缩放为负,但仅当网格碰撞器不是凸形时才为负

注意:当您将 MeshCollider 组件添加到已存在 MeshFilter 组件的游戏对象时,sharedMesh 属性会自动设置,这可能会触发重新烘焙。



以下是一个简单的示例,在主线程上烘焙网格

using UnityEngine;

public class MinimalTest : MonoBehaviour { public Mesh mesh;

private MeshCollider collider;

private MeshColliderCookingOptions cookingOptions = MeshColliderCookingOptions.UseFastMidphase & MeshColliderCookingOptions.CookForFasterSimulation;

private void OnEnable() { // Bake this Mesh to use later. Physics.BakeMesh(mesh.GetInstanceID(), false, cookingOptions); }

public void FixedUpdate() { // If the collider wasn't yet created - create it now. if (collider == null) { // No mesh baking will happen here because the mesh was pre-baked, making instantiation faster. collider = new GameObject().AddComponent<MeshCollider>(); collider.cookingOptions = cookingOptions; collider.sharedMesh = mesh; } } }

BakeMesh 是线程安全的,并在其被调用所在的线程上执行计算。但是,不要同时从多个线程中对同一网格调用 BakeMesh,因为这会导致未定义的行为。您可以将 BakeMesh 与 C# 作业系统结合使用。此示例展示如何在多个线程上烘焙网格,以便在主线程上花费更少的时间实例化网格碰撞器。

using Unity.Collections;
using Unity.Jobs;
using UnityEngine;

public struct BakeJob : IJobParallelFor { private NativeArray<int> meshIds;

public BakeJob(NativeArray<int> meshIds) { this.meshIds = meshIds; }

public void Execute(int index) { Physics.BakeMesh(meshIds[index], false); } }

public class JobifiedBaking : MonoBehaviour { public Mesh[] meshes; public int meshesPerJob = 10;

// Bake all the Meshes off of the main thread, and then instantiate on the main thread. private void OnEnable() { // You cannot access GameObjects and Components from other threads directly. // As such, you need to create a native array of instance IDs that BakeMesh will accept. NativeArray<int> meshIds = new NativeArray<int>(meshes.Length, Allocator.TempJob);

for (int i = 0; i < meshes.Length; ++i) { meshIds[i] = meshes[i].GetInstanceID(); }

// This spreads the expensive operation over all cores. var job = new BakeJob(meshIds); job.Schedule(meshIds.Length, meshesPerJob).Complete();

meshIds.Dispose();

// Now instantiate colliders on the main thread. for (int i = 0; i < meshes.Length; ++i) { new GameObject().AddComponent<MeshCollider>().sharedMesh = meshes[i]; } } }