92 lines
3.3 KiB
C#
92 lines
3.3 KiB
C#
using UnityEngine;
|
|
|
|
namespace Ashwild.Building
|
|
{
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public class BuiltStructure : MonoBehaviour
|
|
{
|
|
#region State
|
|
|
|
/// <summary>
|
|
/// Every child renderer, cached so the highlight can swap and restore their materials.
|
|
/// </summary>
|
|
private Renderer[] renderers;
|
|
|
|
/// <summary>
|
|
/// Each renderer's original materials, kept so the swap is fully reversible.
|
|
/// </summary>
|
|
private Material[][] baseMaterials;
|
|
|
|
/// <summary>
|
|
/// Whether the demolition material is currently applied, so swaps stay idempotent.
|
|
/// </summary>
|
|
private bool highlighted;
|
|
|
|
#endregion
|
|
|
|
#region Unity Lifecycle
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
private void Awake()
|
|
{
|
|
renderers = GetComponentsInChildren<Renderer>(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
|
|
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restores each renderer's authored materials. No-op when not highlighted.
|
|
/// </summary>
|
|
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
|
|
}
|
|
}
|