Physics.BakeMesh
Declaration
public static void BakeMesh(EntityId meshEntityId, bool convex);Obsolete public static void BakeMesh(int meshID, bool convex);Параметры
| Параметр | Описание |
|---|---|
| meshID | Экземпляр ID сетки, из которой будут получены данные о столкновениях. |
| выпуклый | Флаг, указывающий, следует ли запекать выпуклую геометрию или нет. |
| meshEntityId | EntityId сетки, из которой будут получены данные о столкновениях. |
Описание
Подготавливает сетку для использования с MeshCollider и использует стандартные параметры приготовления.
Declaration
public static void BakeMesh(EntityId meshEntityId, bool convex, MeshColliderCookingOptions cookingOptions);Obsolete public static void BakeMesh(int meshID, bool convex, MeshColliderCookingOptions cookingOptions);Параметры
| Параметр | Описание |
|---|---|
| meshID | Экземпляр ID сетки, из которой будут получены данные о столкновениях. |
| выпуклый | Флаг, указывающий, следует ли запекать выпуклую геометрию или нет. |
| cookingOptions | Варианты приготовления, которые следует использовать при выпечке сетки. |
| meshEntityId | EntityId сетки, из которой будут получены данные о столкновениях. |
Описание
Подготовка сетки для использования с MeshCollider.
Для того, чтобы меш могла быть использована с MeshCollider, система физики должна сначала подготовить её, создав структуры ускорения пространственного поиска. Этот процесс называется запеканием.
Обычно компонент MeshCollider требует выпекаемой меши, когда пользователь создает его экземпляр, или когда пользователь устанавливает новую меш для него с помощью свойства sharedMesh. Запекание является ресурсоемкой операцией, поэтому вы можете запустить ее в подходящий момент (например, во время менее ресурсоемкой части приложения), или распределить нагрузку между всеми доступными ядрами, если несколько мешей требуют запекания. С другой стороны, цель этой функции состоит в предварительном выпекании меши для последующего использования, так что дальнейшее запекание не требуется.
Экземпляр меши хранит выпекаемую меш.
Процесс запекания требует доступа к геометрии меши. Если пользователь вызывает метод BakeMesh в Проигрывателе, метод BakeMesh требует включения свойства Чтение/Запись меши. Однако использование метода BakeMesh в Редакторе не требует дополнительных настроек, поскольку геометрия всегда доступна в Редакторе.
Компонент MeshCollider повторно использует выпекаемую меш, если и только если выполнены все следующие условия:
- MeshCollider's cookingOptions точно такие же, как были указаны во время запекания,
- Преобразование MeshCollider позволяет разделять сетку (*),
- Геометрия сетки не была изменена со времени последней запекания.
В этом контексте преобразование MeshCollider разрешает совместное использование сетки, если:
- ее масштабирование не является отрицательным и не является искаженным, или
- Его масштабирование отрицательно, но только когда MeshCollider не выпукло
Обратите внимание: Когда вы добавляете компонент MeshCollider в GameObject, в котором уже присутствует компонент 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.GetEntityId(), 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#. В этом примере показано, как приготовить меши на нескольких потоках, чтобы инстанционирование MeshCollider занимало меньше времени на главном потоке.
using Unity.Collections; using Unity.Jobs; using UnityEngine;
public struct BakeJob : IJobParallelFor { private NativeArray<EntityId> meshIds;
public BakeJob(NativeArray<EntityId> 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 EntityIds that BakeMesh will accept. NativeArray<EntityId> meshIds = new NativeArray<EntityId>(meshes.Length, Allocator.TempJob);
for (int i = 0; i < meshes.Length; ++i) { meshIds[i] = meshes[i].GetEntityId(); }
// 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]; } } }