This commit is contained in:
2026-08-14 18:51:23 +05:00
parent d559ab338a
commit 173bbb165c
29 changed files with 961 additions and 227 deletions
@@ -4,84 +4,94 @@ using UnityEngine;
[DisallowMultipleComponent]
public sealed class MapTargetController : MonoBehaviour
{
[Header("Target Settings")]
[SerializeField, Min(0)] private int targetCount = 5;
[SerializeField, Min(0f)] private float targetMovementSpeed = 1f;
[Header("Random Wave Settings")]
[SerializeField, Min(0)] private int targetsPerWave = 5;
[SerializeField] private TargetConfig[] randomTargetConfigs = System.Array.Empty<TargetConfig>();
private readonly List<MapTarget> targets = new();
[Header("Current Wave (Runtime)")]
[SerializeField, Min(0)] private int currentWave;
[SerializeField] private List<MapTarget> currentWaveTargets = new();
private readonly List<MapTarget> pooledTargets = new();
private MapCoordinateSystem coordinateSystem;
private MapTarget targetPrefab;
private Transform targetParent;
private MapPlayer player;
private bool isConfigured;
public IReadOnlyList<MapTarget> Targets => targets;
public int TargetCount => targetCount;
public float TargetMovementSpeed => targetMovementSpeed;
public IReadOnlyList<MapTarget> Targets => currentWaveTargets;
public int CurrentWave => currentWave;
public int TargetsPerWave => targetsPerWave;
private void Start()
{
if (currentWave == 0)
StartNextWave();
}
private void OnValidate()
{
targetCount = Mathf.Max(0, targetCount);
targetMovementSpeed = Mathf.Max(0f, targetMovementSpeed);
targetsPerWave = Mathf.Max(0, targetsPerWave);
currentWave = Mathf.Max(0, currentWave);
}
public void Configure(
MapCoordinateSystem newCoordinateSystem,
MapTarget newTargetPrefab,
Transform newTargetParent)
Transform newTargetParent,
MapPlayer newPlayer)
{
coordinateSystem = newCoordinateSystem;
targetPrefab = newTargetPrefab;
targetParent = newTargetParent != null ? newTargetParent : transform;
isConfigured = coordinateSystem != null &&
coordinateSystem.HasValidCorners() &&
targetPrefab != null;
player = newPlayer;
isConfigured = coordinateSystem != null && coordinateSystem.HasValidCorners();
pooledTargets.Clear();
foreach (MapTarget existingTarget in targetParent.GetComponentsInChildren<MapTarget>(true))
{
existingTarget.SetVisualsVisible(false);
existingTarget.gameObject.SetActive(false);
pooledTargets.Add(existingTarget);
}
}
public bool StartNextWave()
{
if (!isConfigured || !HasValidTargetConfig())
{
Debug.LogWarning("Target controller has no coordinate system or valid TargetConfig.", this);
return false;
}
RetireCurrentWave();
currentWave++;
for (int index = 0; index < targetsPerWave; index++)
{
TargetConfig config = GetRandomValidConfig();
if (config == null)
break;
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.gameObject.SetActive(true);
currentWaveTargets.Add(target);
}
return currentWaveTargets.Count > 0 || targetsPerWave == 0;
}
public void CreateAndPlaceTargets()
{
if (!isConfigured)
{
Debug.LogWarning("Target system is not configured.", this);
return;
}
RegisterExistingTargets();
while (targets.Count < targetCount)
{
MapTarget target = Instantiate(targetPrefab, targetParent);
target.name = $"Target_{targets.Count + 1}";
targets.Add(target);
}
while (targets.Count > targetCount)
{
int lastIndex = targets.Count - 1;
MapTarget target = targets[lastIndex];
targets.RemoveAt(lastIndex);
if (target != null)
Destroy(target.gameObject);
}
for (int index = 0; index < targets.Count; index++)
{
MapTarget target = targets[index];
if (target == null)
continue;
target.Configure(
coordinateSystem,
GetRandomCoordinates(),
targetMovementSpeed,
Random.insideUnitCircle.normalized);
target.SetVisualsVisible(false);
}
StartNextWave();
}
public void SetTargetVisualsVisible(bool isVisible)
{
foreach (MapTarget target in targets)
foreach (MapTarget target in currentWaveTargets)
{
if (target != null)
target.SetVisualsVisible(isVisible);
@@ -90,19 +100,68 @@ public sealed class MapTargetController : MonoBehaviour
public MapTarget GetTarget(int index)
{
return index >= 0 && index < targets.Count ? targets[index] : null;
return index >= 0 && index < currentWaveTargets.Count
? currentWaveTargets[index]
: null;
}
private void RegisterExistingTargets()
private void RetireCurrentWave()
{
targets.Clear();
MapTarget[] existingTargets = targetParent.GetComponentsInChildren<MapTarget>(true);
foreach (MapTarget target in existingTargets)
foreach (MapTarget target in currentWaveTargets)
{
if (target != null && !targets.Contains(target))
targets.Add(target);
if (target == null)
continue;
target.SetVisualsVisible(false);
target.gameObject.SetActive(false);
if (!pooledTargets.Contains(target))
pooledTargets.Add(target);
}
currentWaveTargets.Clear();
}
private MapTarget GetPooledTarget(TargetConfig config)
{
for (int index = pooledTargets.Count - 1; index >= 0; index--)
{
MapTarget candidate = pooledTargets[index];
if (candidate == null)
{
pooledTargets.RemoveAt(index);
continue;
}
if (candidate.GetType() != config.TargetPrefab.GetType())
continue;
pooledTargets.RemoveAt(index);
return candidate;
}
return null;
}
private bool HasValidTargetConfig()
{
return GetRandomValidConfig() != null;
}
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()