Refactor: Remove TowerRegistry, replicate towers by TypeID
Removing redundant workflow and making sure there's just once source of truth for the list of available towers.
This commit is contained in:
parent
63b8195985
commit
a87b221d87
5 changed files with 33 additions and 159 deletions
|
|
@ -1,5 +1,4 @@
|
|||
// Assets/_Project/Scripts/Gameplay/TowerInstance.cs
|
||||
using Unity.Collections;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using TD.Core;
|
||||
|
|
@ -32,11 +31,11 @@ namespace TD.Gameplay
|
|||
/// <see cref="SetOccupied"/> are idempotent writes, so double-stamping is safe.</para>
|
||||
///
|
||||
/// <para><b>Definition reference replication.</b> TowerDefinition assets live in the
|
||||
/// project on all clients. We replicate the asset by name via a
|
||||
/// <see cref="NetworkVariable{T}"/> holding a <c>FixedString64Bytes</c>, then look
|
||||
/// up the asset locally. This avoids serializing the full ScriptableObject over the
|
||||
/// network. The lookup uses a <see cref="TowerRegistry"/> singleton that must be
|
||||
/// present in the scene. (Temporary: will be driven by RaceDefinition in Path E.)</para>
|
||||
/// project on all clients. We replicate the tower's <c>TowerTypeId</c> (its index in
|
||||
/// <see cref="TowerPlacementManager"/>'s catalog) via a <see cref="NetworkVariable{T}"/>,
|
||||
/// then resolve the full asset locally with <see cref="TowerPlacementManager.GetDefinition"/>.
|
||||
/// This avoids serializing the ScriptableObject over the network and reuses the same
|
||||
/// identifier placement and the deck already use — a single source of truth.</para>
|
||||
///
|
||||
/// <para><b>Combat.</b> No combat logic here yet. Combat fields live stubbed on
|
||||
/// <see cref="TowerDefinition"/>; they will be consumed by a future
|
||||
|
|
@ -58,12 +57,13 @@ namespace TD.Gameplay
|
|||
|
||||
// ----- Networked state ------------------------------------------------
|
||||
|
||||
// The name of the TowerDefinition asset for this tower. Replicated so all
|
||||
// clients can look up the full definition locally without sending the whole
|
||||
// ScriptableObject over the wire.
|
||||
private readonly NetworkVariable<FixedString64Bytes> definitionName =
|
||||
new NetworkVariable<FixedString64Bytes>(
|
||||
default,
|
||||
// The TowerTypeId (index into TowerPlacementManager's catalog) for this tower.
|
||||
// Replicated so every client resolves the full definition locally via the catalog —
|
||||
// the same identifier placement and the deck already use. 0 = unset/invalid (the
|
||||
// reserved catalog index). Replaces the old replicate-by-name + TowerRegistry path.
|
||||
private readonly NetworkVariable<int> definitionTypeId =
|
||||
new NetworkVariable<int>(
|
||||
0,
|
||||
readPerm: NetworkVariableReadPermission.Everyone,
|
||||
writePerm: NetworkVariableWritePermission.Server);
|
||||
|
||||
|
|
@ -95,8 +95,8 @@ namespace TD.Gameplay
|
|||
|
||||
// ----- Local resolved state -------------------------------------------
|
||||
|
||||
// Resolved on every client in OnNetworkSpawn from definitionName.
|
||||
// Null if the lookup fails (missing TowerRegistry or unknown name).
|
||||
// Resolved on every client in OnNetworkSpawn from definitionTypeId via the catalog.
|
||||
// Null if the lookup fails (TypeId not in the catalog on this peer).
|
||||
private TowerDefinition resolvedDefinition;
|
||||
|
||||
// ----- Pre-spawn initialization data ----------------------------------
|
||||
|
|
@ -192,7 +192,7 @@ namespace TD.Gameplay
|
|||
hasPendingInit = true;
|
||||
|
||||
// Cache the resolved definition on the server immediately — clients
|
||||
// will resolve via the registry lookup once definitionName arrives.
|
||||
// resolve from the replicated TowerTypeId via the catalog once it arrives.
|
||||
resolvedDefinition = def;
|
||||
}
|
||||
|
||||
|
|
@ -206,7 +206,17 @@ namespace TD.Gameplay
|
|||
// every client sees correct values on its very first OnNetworkSpawn.
|
||||
if (IsServer && hasPendingInit)
|
||||
{
|
||||
definitionName.Value = new FixedString64Bytes(pendingDefinition.name);
|
||||
// Resolve the catalog index for this definition and replicate that.
|
||||
int typeId = 0;
|
||||
var pm = TowerPlacementManager.Instance;
|
||||
if (pm == null || !pm.TryGetTypeId(pendingDefinition, out typeId))
|
||||
{
|
||||
Debug.LogError($"[TowerInstance] Could not resolve a TowerTypeId for " +
|
||||
$"'{pendingDefinition?.name}'. Ensure it is in the " +
|
||||
$"TowerPlacementManager catalog (towerDefinitions).");
|
||||
}
|
||||
|
||||
definitionTypeId.Value = typeId;
|
||||
anchorTile.Value = pendingAnchor;
|
||||
ownerSlot.Value = pendingOwner;
|
||||
|
||||
|
|
@ -331,27 +341,13 @@ namespace TD.Gameplay
|
|||
// Already resolved (server path via InitializeServer).
|
||||
if (resolvedDefinition != null) return;
|
||||
|
||||
string defName = definitionName.Value.ToString();
|
||||
if (string.IsNullOrEmpty(defName))
|
||||
{
|
||||
Debug.LogError($"[TowerInstance] NetworkObject {NetworkObjectId}: " +
|
||||
$"definitionName is empty. Cannot resolve TowerDefinition.");
|
||||
return;
|
||||
}
|
||||
|
||||
var registry = TowerRegistry.Instance;
|
||||
if (registry == null)
|
||||
{
|
||||
Debug.LogError($"[TowerInstance] NetworkObject {NetworkObjectId}: " +
|
||||
$"No TowerRegistry found in scene. Cannot resolve '{defName}'.");
|
||||
return;
|
||||
}
|
||||
|
||||
resolvedDefinition = registry.Get(defName);
|
||||
int typeId = definitionTypeId.Value;
|
||||
resolvedDefinition = TowerPlacementManager.GetDefinition(typeId);
|
||||
if (resolvedDefinition == null)
|
||||
{
|
||||
Debug.LogError($"[TowerInstance] NetworkObject {NetworkObjectId}: " +
|
||||
$"TowerRegistry does not contain a definition named '{defName}'.");
|
||||
$"no TowerDefinition for TypeId {typeId}. Is the " +
|
||||
$"TowerPlacementManager catalog populated on this peer?");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue