Finish Phase 1.2 HUD: selection wiring, command grid context, build progress bar
- Builder.DisplayName: stub property ("Builder (P{n})") for portrait label; swaps
to real player name when MatchState lands in Phase 1.3
- HUDController: subscribe SelectionState.OnSelectionChanged in OnEnable/OnDisable;
HandleSelectionChanged drives portrait label + grays out command grid when nothing
is selected; Start() seeds initial state in case builder auto-selected before Start
- BuildSiteVisual: ComputeProgressNormalized() public API ([0,1], safe on any client);
OnNetworkSpawn spawns a non-networked BuildProgressBar child
- BuildProgressBar: new world-space uGUI Canvas bar; green while Constructing, yellow
while Paused, hidden while Queued; billboards to Camera.main each LateUpdate;
auto-destroyed when parent BuildSiteVisual despawns
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6c37e569ab
commit
bc557af624
4 changed files with 135 additions and 0 deletions
|
|
@ -4,6 +4,7 @@ using Unity.Netcode;
|
|||
using UnityEngine;
|
||||
using TD.Core;
|
||||
using TD.Towers;
|
||||
using TD.UI;
|
||||
|
||||
namespace TD.Gameplay
|
||||
{
|
||||
|
|
@ -186,6 +187,20 @@ namespace TD.Gameplay
|
|||
/// <summary>Accumulated construction time (across pause/resume cycles). Used on resume.</summary>
|
||||
public float AccumulatedConstructionTime => accumulatedConstructionTime.Value;
|
||||
|
||||
/// <summary>
|
||||
/// Returns [0,1] normalized construction progress. Safe to call on any client.
|
||||
/// Returns 0 while Queued; freezes at accumulated fraction while Paused.
|
||||
/// </summary>
|
||||
public float ComputeProgressNormalized()
|
||||
{
|
||||
float bt = buildTime.Value;
|
||||
if (bt <= 0f) return 0f;
|
||||
float currentRunElapsed = constructionStartServerTime.Value > 0f
|
||||
? (float)NetworkManager.Singleton.ServerTime.Time - constructionStartServerTime.Value
|
||||
: 0f;
|
||||
return Mathf.Clamp01((currentRunElapsed + accumulatedConstructionTime.Value) / bt);
|
||||
}
|
||||
|
||||
// ----- Pre-spawn init data (server) -------------------------------
|
||||
|
||||
private string pendingDefName;
|
||||
|
|
@ -251,6 +266,12 @@ namespace TD.Gameplay
|
|||
|
||||
// Apply initial visual state based on the (now-replicated) values.
|
||||
ApplyStageVisual(currentStage.Value);
|
||||
|
||||
// Attach a local (non-networked) progress bar — each client creates its own.
|
||||
// Destroyed automatically when this NetworkObject is despawned (it's a child).
|
||||
var barHost = new GameObject("ProgressBar");
|
||||
barHost.transform.SetParent(transform, false);
|
||||
barHost.AddComponent<BuildProgressBar>().Initialize(this);
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
|
|
|
|||
|
|
@ -156,6 +156,17 @@ namespace TD.Gameplay
|
|||
/// <summary>Maximum jobs allowed in the queue.</summary>
|
||||
public int MaxQueueDepth => settings.maxQueueDepth;
|
||||
|
||||
/// <summary>Display name shown in the HUD portrait. Stub until MatchState provides player names.</summary>
|
||||
public string DisplayName
|
||||
{
|
||||
get
|
||||
{
|
||||
PlayerSlot slot = OwnerToSlot(OwnerClientId);
|
||||
int n = (int)slot;
|
||||
return n >= 1 && n <= 9 ? $"Builder (P{n})" : "Builder";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>True if a tile is currently part of any queued or constructing job.</summary>
|
||||
/// <remarks>
|
||||
/// Used by <c>TowerPlacementManager</c> to reject placement on tiles already
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue