Задать вопрос
@dima89e

Почему Front сторона у ВСЕХ блоков, а не тех которых я добавил в переменную удалилась?

почему Front сторона у ВСЕХ блоков, а не тех которых я добавил в переменную удалилась? они там не ProBuilder блоки были, а префабы Dirt, что не так?

using UnityEngine;
using System.Collections.Generic;

#if USING_PROBUILDER
using UnityEditor.ProBuilder;
using UnityEditor.ProBuilder.MeshOperations;
#endif

public class WorldBaker3 : MonoBehaviour
{
  public enum CubeSide { Right, Left, Top, Bottom, Front, Back, Null }

  [SerializeField] private GameObject[] blocks;
  [SerializeField] private LayerMask groundLayer;

  const float BlockScale = 0.99f;

  [ContextMenu("Bake World")]
  public void BakeWorld()
  {
    foreach (GameObject block in blocks)
    {
      if (block == null) continue;

      if (Physics.Raycast(block.transform.position, Vector3.right, BlockScale, groundLayer)) RemoveSide(block, CubeSide.Right);
      if (Physics.Raycast(block.transform.position, Vector3.left, BlockScale, groundLayer)) RemoveSide(block, CubeSide.Left);
      if (Physics.Raycast(block.transform.position, Vector3.forward, BlockScale, groundLayer)) RemoveSide(block, CubeSide.Front);
      if (Physics.Raycast(block.transform.position, Vector3.back, BlockScale, groundLayer)) RemoveSide(block, CubeSide.Back);
      if (Physics.Raycast(block.transform.position, Vector3.up, BlockScale, groundLayer)) RemoveSide(block, CubeSide.Top);
      if (Physics.Raycast(block.transform.position, Vector3.down, BlockScale, groundLayer)) RemoveSide(block, CubeSide.Bottom);
    }
  }

  private void RemoveSide(GameObject block, CubeSide side)
  {
#if USING_PROBUILDER
            ProBuilderMesh pbMesh = block.GetComponent<ProBuilderMesh>();
            if (pbMesh != null)
            {
                RemoveProBuilderSideWithMaterials(pbMesh, side);
                continue;
            }
#endif

    RemoveStandardMeshSide(block, side);
  }

#if USING_PROBUILDER
    private void RemoveProBuilderSideWithMaterials(ProBuilderMesh pbMesh, CubeSide side)
    {
        if (side == CubeSide.Null) return;

        Vector3 sideNormal = GetSideNormal(side);
        List<Face> facesToRemove = new List<Face>();

        // Собираем все грани, которые нужно удалить
        foreach (Face face in pbMesh.faces)
        {
            Vector3 normal = pbMesh.GetFaceNormal(face);
            if (Vector3.Dot(normal, sideNormal) > 0.9f)
            {
                facesToRemove.Add(face);
            }
        }

        // Удаляем грани, сохраняя индексы материалов
        pbMesh.DeleteFaces(facesToRemove);

        // Важно: обновляем меш и пересчитываем UV, нормали и материалы
        pbMesh.ToMesh();
        pbMesh.Refresh(); // Обновляет меш и материалы
    }
#endif

  private void RemoveStandardMeshSide(GameObject block, CubeSide side)
  {
    if (side == CubeSide.Null) return;

    MeshFilter meshFilter = block.GetComponent<MeshFilter>();
    if (meshFilter == null || meshFilter.sharedMesh == null) return;

    Mesh mesh = meshFilter.sharedMesh;
    Vector3[] vertices = mesh.vertices;
    int[] triangles = mesh.triangles;
    int subMeshCount = mesh.subMeshCount;

    // Создаем список новых треугольников для каждого сабмеша
    List<int>[] newTrianglesPerSubMesh = new List<int>[subMeshCount];
    for (int i = 0; i < subMeshCount; i++)
    {
      newTrianglesPerSubMesh[i] = new List<int>();
    }

    Vector3 sideNormal = GetSideNormal(side);

    // Проходим по всем сабмешам (материалам)
    for (int subMesh = 0; subMesh < subMeshCount; subMesh++)
    {
      int[] subMeshTris = mesh.GetTriangles(subMesh);

      for (int i = 0; i < subMeshTris.Length; i += 3)
      {
        Vector3 v1 = vertices[subMeshTris[i]];
        Vector3 v2 = vertices[subMeshTris[i + 1]];
        Vector3 v3 = vertices[subMeshTris[i + 2]];

        Vector3 faceNormal = Vector3.Cross(v2 - v1, v3 - v1).normalized;

        // Если грань не принадлежит удаляемой стороне, сохраняем её
        if (Vector3.Dot(faceNormal, sideNormal) <= 0.9f)
        {
          newTrianglesPerSubMesh[subMesh].Add(subMeshTris[i]);
          newTrianglesPerSubMesh[subMesh].Add(subMeshTris[i + 1]);
          newTrianglesPerSubMesh[subMesh].Add(subMeshTris[i + 2]);
        }
      }
    }

    // Применяем новые треугольники к каждому сабмешу
    mesh.subMeshCount = subMeshCount;
    for (int i = 0; i < subMeshCount; i++)
    {
      mesh.SetTriangles(newTrianglesPerSubMesh[i], i);
    }

    mesh.RecalculateNormals();

    // Обновляем коллайдер, если есть
    MeshCollider meshCollider = block.GetComponent<MeshCollider>();
    if (meshCollider != null)
    {
      meshCollider.sharedMesh = mesh;
    }
  }

  private Vector3 GetSideNormal(CubeSide side)
  {
    switch (side)
    {
      case CubeSide.Right: return Vector3.right;
      case CubeSide.Left: return Vector3.left;
      case CubeSide.Top: return Vector3.up;
      case CubeSide.Bottom: return Vector3.down;
      case CubeSide.Front: return Vector3.forward;
      case CubeSide.Back: return Vector3.back;
      default: return Vector3.zero;
    }
  }
}


6837d5754b76c299292745.png6837d578ac98d203945713.png6837d57c8aaf3887574631.png
  • Вопрос задан
  • 24 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы