using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using Random = UnityEngine.Random; public class BuildingMaterialReplacer : MonoBehaviour { [SerializeField] private Material sourceMaterial; [SerializeField] private Material[] newMaterials; private readonly Dictionary _bounds = new(); private readonly Dictionary _materials = new(); [ContextMenu(nameof(Replace))] private void Replace() { _bounds.Clear(); _materials.Clear(); foreach (var meshRenderer in GetComponentsInChildren()) { var sharedMaterials = meshRenderer.sharedMaterials; var index = sharedMaterials.ToList().IndexOf(sourceMaterial); if (index is -1) continue; var meshBounds = meshRenderer.bounds; try { foreach (var (id, bound) in _bounds) { if (bound.Contains(meshBounds.center)) { sharedMaterials[index] = _materials[id]; meshRenderer.sharedMaterials = sharedMaterials; throw new OperationCanceledException(); } } } catch (OperationCanceledException) { continue; } sharedMaterials[index] = newMaterials[Random.Range(0, newMaterials.Length - 1)]; meshRenderer.sharedMaterials = sharedMaterials; meshBounds.Encapsulate(new Bounds(meshBounds.center, Vector3.up * 128)); _bounds[meshRenderer.GetInstanceID()] = meshBounds; _materials[meshRenderer.GetInstanceID()] = sharedMaterials[index]; } } }