Map mehanic ready to multiplayer
This commit is contained in:
@@ -1,33 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class MapTargetController : MonoBehaviour
|
||||
{
|
||||
[Header("Random Wave Settings")]
|
||||
[Header("Wave Settings")]
|
||||
[SerializeField, Min(0)] private int targetsPerWave = 5;
|
||||
[SerializeField] private TargetConfig[] randomTargetConfigs = System.Array.Empty<TargetConfig>();
|
||||
[SerializeField] private TargetConfig[] randomTargetConfigs = Array.Empty<TargetConfig>();
|
||||
[SerializeField] private bool showLiveTargetVisuals;
|
||||
|
||||
[Header("Current Wave (Runtime)")]
|
||||
[SerializeField, Min(0)] private int currentWave;
|
||||
[SerializeField] private List<MapTarget> currentWaveTargets = new();
|
||||
|
||||
private readonly List<MapTarget> pooledTargets = new();
|
||||
private readonly Dictionary<int, MapTarget> targetsById = new();
|
||||
private readonly HashSet<int> synchronizedTargetIds = new();
|
||||
private MapCoordinateSystem coordinateSystem;
|
||||
private Transform targetParent;
|
||||
private MapPlayer player;
|
||||
private bool isConfigured;
|
||||
|
||||
public IReadOnlyList<MapTarget> Targets => currentWaveTargets;
|
||||
public IReadOnlyList<TargetConfig> TargetConfigs => randomTargetConfigs;
|
||||
public int CurrentWave => currentWave;
|
||||
public int TargetsPerWave => targetsPerWave;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (currentWave == 0)
|
||||
StartNextWave();
|
||||
}
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
targetsPerWave = Mathf.Max(0, targetsPerWave);
|
||||
@@ -42,9 +40,10 @@ public sealed class MapTargetController : MonoBehaviour
|
||||
coordinateSystem = newCoordinateSystem;
|
||||
targetParent = newTargetParent != null ? newTargetParent : transform;
|
||||
player = newPlayer;
|
||||
isConfigured = coordinateSystem != null && coordinateSystem.HasValidCorners();
|
||||
|
||||
pooledTargets.Clear();
|
||||
targetsById.Clear();
|
||||
currentWaveTargets.Clear();
|
||||
foreach (MapTarget existingTarget in targetParent.GetComponentsInChildren<MapTarget>(true))
|
||||
{
|
||||
existingTarget.SetVisualsVisible(false);
|
||||
@@ -53,44 +52,78 @@ public sealed class MapTargetController : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public bool StartNextWave()
|
||||
public void ApplyNetworkTargets(
|
||||
IReadOnlyList<MapTargetNetworkState> states,
|
||||
int wave)
|
||||
{
|
||||
if (!isConfigured || !HasValidTargetConfig())
|
||||
currentWave = Mathf.Max(0, wave);
|
||||
synchronizedTargetIds.Clear();
|
||||
|
||||
for (int index = 0; index < states.Count; index++)
|
||||
{
|
||||
Debug.LogWarning("Target controller has no coordinate system or valid TargetConfig.", this);
|
||||
return false;
|
||||
}
|
||||
MapTargetNetworkState state = states[index];
|
||||
TargetConfig config = GetConfig(state.ConfigIndex);
|
||||
if (config == null || config.TargetPrefab == null)
|
||||
continue;
|
||||
|
||||
RetireCurrentWave();
|
||||
currentWave++;
|
||||
synchronizedTargetIds.Add(state.TargetId);
|
||||
if (!targetsById.TryGetValue(state.TargetId, out MapTarget target) || target == null)
|
||||
{
|
||||
target = GetPooledTarget(config);
|
||||
if (target == null)
|
||||
target = Instantiate(config.TargetPrefab, targetParent);
|
||||
|
||||
for (int index = 0; index < targetsPerWave; index++)
|
||||
{
|
||||
TargetConfig config = GetRandomValidConfig();
|
||||
if (config == null)
|
||||
break;
|
||||
targetsById[state.TargetId] = target;
|
||||
currentWaveTargets.Add(target);
|
||||
}
|
||||
|
||||
MapTarget target = GetPooledTarget(config);
|
||||
if (target == null)
|
||||
target = Instantiate(config.TargetPrefab, targetParent);
|
||||
|
||||
target.name = $"Wave {currentWave} - {config.name} - {index + 1}";
|
||||
target.Configure(config, coordinateSystem, GetRandomCoordinates(), player);
|
||||
target.SetVisualsVisible(false);
|
||||
target.name = $"Wave {currentWave} - {config.name} - {state.TargetId}";
|
||||
target.Configure(config, coordinateSystem, player);
|
||||
target.ApplyNetworkState(state);
|
||||
target.SetVisualsVisible(showLiveTargetVisuals);
|
||||
target.gameObject.SetActive(true);
|
||||
currentWaveTargets.Add(target);
|
||||
}
|
||||
|
||||
return currentWaveTargets.Count > 0 || targetsPerWave == 0;
|
||||
for (int index = currentWaveTargets.Count - 1; index >= 0; index--)
|
||||
{
|
||||
MapTarget target = currentWaveTargets[index];
|
||||
if (target != null && synchronizedTargetIds.Contains(target.TargetId))
|
||||
continue;
|
||||
|
||||
RetireTarget(target);
|
||||
currentWaveTargets.RemoveAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateAndPlaceTargets()
|
||||
public TargetConfig GetConfig(int index) =>
|
||||
index >= 0 && index < randomTargetConfigs.Length
|
||||
? randomTargetConfigs[index]
|
||||
: null;
|
||||
|
||||
public int GetRandomValidConfigIndex()
|
||||
{
|
||||
StartNextWave();
|
||||
if (randomTargetConfigs == null || randomTargetConfigs.Length == 0)
|
||||
return -1;
|
||||
|
||||
int startIndex = UnityEngine.Random.Range(0, randomTargetConfigs.Length);
|
||||
for (int offset = 0; offset < randomTargetConfigs.Length; offset++)
|
||||
{
|
||||
int index = (startIndex + offset) % randomTargetConfigs.Length;
|
||||
TargetConfig config = randomTargetConfigs[index];
|
||||
if (config != null && config.TargetPrefab != null)
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool HasValidConfiguration() =>
|
||||
coordinateSystem != null && coordinateSystem.HasValidCorners() &&
|
||||
GetRandomValidConfigIndex() >= 0;
|
||||
|
||||
public void SetTargetVisualsVisible(bool isVisible)
|
||||
{
|
||||
showLiveTargetVisuals = isVisible;
|
||||
foreach (MapTarget target in currentWaveTargets)
|
||||
{
|
||||
if (target != null)
|
||||
@@ -98,28 +131,15 @@ public sealed class MapTargetController : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public MapTarget GetTarget(int index)
|
||||
{
|
||||
return index >= 0 && index < currentWaveTargets.Count
|
||||
public MapTarget GetTarget(int index) =>
|
||||
index >= 0 && index < currentWaveTargets.Count
|
||||
? currentWaveTargets[index]
|
||||
: null;
|
||||
}
|
||||
|
||||
private void RetireCurrentWave()
|
||||
public bool StartNextWave()
|
||||
{
|
||||
foreach (MapTarget target in currentWaveTargets)
|
||||
{
|
||||
if (target == null)
|
||||
continue;
|
||||
|
||||
target.SetVisualsVisible(false);
|
||||
target.gameObject.SetActive(false);
|
||||
|
||||
if (!pooledTargets.Contains(target))
|
||||
pooledTargets.Add(target);
|
||||
}
|
||||
|
||||
currentWaveTargets.Clear();
|
||||
MapController mapController = FindFirstObjectByType<MapController>();
|
||||
return mapController != null && mapController.StartNextWave();
|
||||
}
|
||||
|
||||
private MapTarget GetPooledTarget(TargetConfig config)
|
||||
@@ -143,30 +163,15 @@ public sealed class MapTargetController : MonoBehaviour
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool HasValidTargetConfig()
|
||||
private void RetireTarget(MapTarget target)
|
||||
{
|
||||
return GetRandomValidConfig() != null;
|
||||
}
|
||||
if (target == null)
|
||||
return;
|
||||
|
||||
private TargetConfig GetRandomValidConfig()
|
||||
{
|
||||
if (randomTargetConfigs == null || randomTargetConfigs.Length == 0)
|
||||
return null;
|
||||
|
||||
int startIndex = Random.Range(0, randomTargetConfigs.Length);
|
||||
for (int offset = 0; offset < randomTargetConfigs.Length; offset++)
|
||||
{
|
||||
TargetConfig config = randomTargetConfigs[(startIndex + offset) % randomTargetConfigs.Length];
|
||||
if (config != null && config.TargetPrefab != null)
|
||||
return config;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Vector2 GetRandomCoordinates()
|
||||
{
|
||||
float maximum = MapCoordinateSystem.CoordinateMaximum;
|
||||
return new Vector2(Random.Range(0f, maximum), Random.Range(0f, maximum));
|
||||
targetsById.Remove(target.TargetId);
|
||||
target.SetVisualsVisible(false);
|
||||
target.gameObject.SetActive(false);
|
||||
if (!pooledTargets.Contains(target))
|
||||
pooledTargets.Add(target);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user