using UnityEngine; namespace Ashwild.Building { /// /// Runtime marker added to every committed structure instance the BuildRegistry spawns, so the /// demolition aim can recognise a build from a raycast hit (GetComponentInParent) and hand its /// root back to the registry to remove. It also owns the demolition highlight: while it is the /// hammer's target the demolition material is added on top of every renderer (an extra overlay /// pass, like the ghost), and removed again when the aim leaves — so the player sees exactly which /// build will break. Pure local visual + a pure tag: nothing about it ever crosses the wire. /// [DisallowMultipleComponent] public class BuiltStructure : MonoBehaviour { #region State /// /// Every child renderer, cached so the highlight can swap and restore their materials. /// private Renderer[] renderers; /// /// Each renderer's original materials, kept so the swap is fully reversible. /// private Material[][] baseMaterials; /// /// Whether the demolition material is currently applied, so swaps stay idempotent. /// private bool highlighted; #endregion #region Unity Lifecycle /// /// Caches every child renderer and its authored materials up front so highlighting is a cheap /// array assignment with no per-frame allocation of the base look. /// private void Awake() { renderers = GetComponentsInChildren(true); baseMaterials = new Material[renderers.Length][]; for (int i = 0; i < renderers.Length; i++) baseMaterials[i] = renderers[i] != null ? renderers[i].sharedMaterials : new Material[0]; } #endregion #region Public API /// /// Adds the demolition material on top of each renderer's authored materials (an extra draw /// pass), marking this build as the hammer's current target without hiding the model. Mirrors /// the ghost overlay. No-op when already highlighted or no material was provided. /// public void Highlight(Material demolitionMaterial) { if (highlighted || demolitionMaterial == null) return; highlighted = true; for (int i = 0; i < renderers.Length; i++) { Renderer r = renderers[i]; if (r == null) continue; Material[] baseMats = baseMaterials[i]; Material[] combined = new Material[baseMats.Length + 1]; for (int j = 0; j < baseMats.Length; j++) combined[j] = baseMats[j]; combined[baseMats.Length] = demolitionMaterial; r.materials = combined; } } /// /// Restores each renderer's authored materials. No-op when not highlighted. /// public void ClearHighlight() { if (!highlighted) return; highlighted = false; for (int i = 0; i < renderers.Length; i++) if (renderers[i] != null) renderers[i].materials = baseMaterials[i]; } #endregion } }