Net.Like.Xue.Tokyo/Packages-Local/Net.BITKit.Bounds.Unity/BuildingMaterialReplacer.cs

66 lines
1.8 KiB
C#

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<int, Bounds> _bounds = new();
private readonly Dictionary<int, Material> _materials = new();
[ContextMenu(nameof(Replace))]
private void Replace()
{
_bounds.Clear();
_materials.Clear();
foreach (var meshRenderer in GetComponentsInChildren<MeshRenderer>())
{
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];
}
}
}