почему 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;
}
}
}

