(Feat) Add Remove Building
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user