IMplement basic Developer Settings
This commit is contained in:
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using Pooling;
|
||||
using AppleHills.Core.Settings;
|
||||
|
||||
namespace Minigames.DivingForPictures
|
||||
{
|
||||
@@ -16,50 +17,17 @@ namespace Minigames.DivingForPictures
|
||||
[Tooltip("List of possible obstacle prefabs to spawn")]
|
||||
[SerializeField] private List<GameObject> obstaclePrefabs;
|
||||
|
||||
[Header("Spawn Settings")]
|
||||
[Tooltip("Time interval between spawn attempts (in seconds)")]
|
||||
[SerializeField] private float spawnInterval = 2f;
|
||||
|
||||
[Tooltip("Random variation in spawn timing (+/- seconds)")]
|
||||
[SerializeField] private float spawnIntervalVariation = 0.5f;
|
||||
|
||||
[Tooltip("Maximum number of spawn position attempts before skipping")]
|
||||
[SerializeField] private int maxSpawnAttempts = 10;
|
||||
|
||||
[Tooltip("Radius around spawn point to check for tile collisions")]
|
||||
[SerializeField] private float spawnCollisionRadius = 1f;
|
||||
|
||||
[Header("Obstacle Properties Randomization")]
|
||||
[Tooltip("Minimum movement speed for spawned obstacles")]
|
||||
[SerializeField] private float minMoveSpeed = 1f;
|
||||
|
||||
[Tooltip("Maximum movement speed for spawned obstacles")]
|
||||
[SerializeField] private float maxMoveSpeed = 4f;
|
||||
|
||||
[Header("Object Pooling")]
|
||||
[Tooltip("Whether to use object pooling for obstacles")]
|
||||
[SerializeField] private bool useObjectPooling = true;
|
||||
|
||||
[Tooltip("Maximum objects per prefab type in pool")]
|
||||
[SerializeField] private int maxPerPrefabPoolSize = 3;
|
||||
|
||||
[Tooltip("Total maximum pool size across all prefab types")]
|
||||
[SerializeField] private int totalMaxPoolSize = 15;
|
||||
|
||||
[Header("Layer Settings")]
|
||||
[Tooltip("Layer mask for tile collision detection during spawn position validation")]
|
||||
[SerializeField] private LayerMask tileLayerMask = -1; // Let user configure which layers to avoid
|
||||
|
||||
[Tooltip("Target layer for spawned obstacles - obstacles will be placed on this layer")]
|
||||
[SerializeField] private int obstacleLayer = 11; // Default to layer 11, but configurable
|
||||
|
||||
[Header("Events")]
|
||||
[Tooltip("Called when an obstacle is spawned")]
|
||||
[Tooltip("Invoked when a new obstacle is spawned")]
|
||||
public UnityEvent<GameObject> onObstacleSpawned;
|
||||
|
||||
[Tooltip("Called when an obstacle is returned to pool")]
|
||||
[Tooltip("Invoked when an obstacle is destroyed or returned to pool")]
|
||||
public UnityEvent<GameObject> onObstacleDestroyed;
|
||||
|
||||
// Settings references
|
||||
private IDivingMinigameSettings _settings;
|
||||
private DivingDeveloperSettings _devSettings;
|
||||
|
||||
// Private fields
|
||||
private ObstaclePool _obstaclePool;
|
||||
private Camera _mainCamera;
|
||||
@@ -75,13 +43,34 @@ namespace Minigames.DivingForPictures
|
||||
{
|
||||
_mainCamera = Camera.main;
|
||||
|
||||
// Get settings from GameManager
|
||||
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
|
||||
_devSettings = GameManager.GetDeveloperSettings<DivingDeveloperSettings>();
|
||||
|
||||
if (_settings == null)
|
||||
{
|
||||
Debug.LogError("[ObstacleSpawner] Failed to load diving minigame settings!");
|
||||
}
|
||||
|
||||
if (_devSettings == null)
|
||||
{
|
||||
Debug.LogError("[ObstacleSpawner] Failed to load diving developer settings!");
|
||||
}
|
||||
|
||||
// Validate obstacle prefabs
|
||||
ValidateObstaclePrefabs();
|
||||
|
||||
if (useObjectPooling)
|
||||
if (_devSettings?.ObstacleUseObjectPooling ?? false)
|
||||
{
|
||||
InitializeObjectPool();
|
||||
}
|
||||
|
||||
// Initialize events if null
|
||||
if (onObstacleSpawned == null)
|
||||
onObstacleSpawned = new UnityEvent<GameObject>();
|
||||
|
||||
if (onObstacleDestroyed == null)
|
||||
onObstacleDestroyed = new UnityEvent<GameObject>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
@@ -100,6 +89,8 @@ namespace Minigames.DivingForPictures
|
||||
/// </summary>
|
||||
private void ValidateObstaclePrefabs()
|
||||
{
|
||||
if (_devSettings == null) return;
|
||||
|
||||
for (int i = 0; i < obstaclePrefabs.Count; i++)
|
||||
{
|
||||
if (obstaclePrefabs[i] == null) continue;
|
||||
@@ -112,10 +103,10 @@ namespace Minigames.DivingForPictures
|
||||
}
|
||||
|
||||
// Ensure the prefab is on the correct layer (using configurable obstacleLayer)
|
||||
if (obstaclePrefabs[i].layer != obstacleLayer)
|
||||
if (obstaclePrefabs[i].layer != _devSettings.ObstacleLayer)
|
||||
{
|
||||
Debug.LogWarning($"Obstacle prefab {obstaclePrefabs[i].name} is not on the configured obstacle layer ({obstacleLayer}). Setting layer automatically.");
|
||||
SetLayerRecursively(obstaclePrefabs[i], obstacleLayer);
|
||||
Debug.LogWarning($"Obstacle prefab {obstaclePrefabs[i].name} is not on the configured obstacle layer ({_devSettings.ObstacleLayer}). Setting layer automatically.");
|
||||
SetLayerRecursively(obstaclePrefabs[i], _devSettings.ObstacleLayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -142,8 +133,8 @@ namespace Minigames.DivingForPictures
|
||||
_obstaclePool = poolGO.AddComponent<ObstaclePool>();
|
||||
|
||||
// Set up pool configuration
|
||||
_obstaclePool.maxPerPrefabPoolSize = maxPerPrefabPoolSize;
|
||||
_obstaclePool.totalMaxPoolSize = totalMaxPoolSize;
|
||||
_obstaclePool.maxPerPrefabPoolSize = _devSettings.ObstacleMaxPerPrefabPoolSize;
|
||||
_obstaclePool.totalMaxPoolSize = _devSettings.ObstacleTotalMaxPoolSize;
|
||||
|
||||
// Convert GameObject list to FloatingObstacle list
|
||||
List<FloatingObstacle> prefabObstacles = new List<FloatingObstacle>(obstaclePrefabs.Count);
|
||||
@@ -230,7 +221,9 @@ namespace Minigames.DivingForPictures
|
||||
while (true)
|
||||
{
|
||||
// Calculate next spawn time with variation
|
||||
float nextSpawnTime = spawnInterval + Random.Range(-spawnIntervalVariation, spawnIntervalVariation);
|
||||
float nextSpawnTime = _settings.EndlessDescenderObstacleSpawnInterval +
|
||||
Random.Range(-_settings.EndlessDescenderObstacleSpawnIntervalVariation,
|
||||
_settings.EndlessDescenderObstacleSpawnIntervalVariation);
|
||||
nextSpawnTime = Mathf.Max(0.1f, nextSpawnTime); // Ensure minimum interval
|
||||
|
||||
yield return new WaitForSeconds(nextSpawnTime);
|
||||
@@ -264,7 +257,7 @@ namespace Minigames.DivingForPictures
|
||||
bool foundValidPosition = false;
|
||||
|
||||
// Try to find a valid spawn position
|
||||
for (int attempts = 0; attempts < maxSpawnAttempts; attempts++)
|
||||
for (int attempts = 0; attempts < _settings.EndlessDescenderObstacleMaxSpawnAttempts; attempts++)
|
||||
{
|
||||
spawnPosition = GetRandomSpawnPosition();
|
||||
|
||||
@@ -277,13 +270,13 @@ namespace Minigames.DivingForPictures
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[ObstacleSpawner] Position {spawnPosition} invalid (attempt {attempts + 1}/{maxSpawnAttempts})");
|
||||
Debug.Log($"[ObstacleSpawner] Position {spawnPosition} invalid (attempt {attempts + 1}/{_settings.EndlessDescenderObstacleMaxSpawnAttempts})");
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundValidPosition)
|
||||
{
|
||||
Debug.LogWarning($"[ObstacleSpawner] SPAWN MISSED: Could not find valid spawn position after {maxSpawnAttempts} attempts at {Time.time:F2}");
|
||||
Debug.LogWarning($"[ObstacleSpawner] SPAWN MISSED: Could not find valid spawn position after {_settings.EndlessDescenderObstacleMaxSpawnAttempts} attempts at {Time.time:F2}");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,7 +299,7 @@ namespace Minigames.DivingForPictures
|
||||
private bool IsValidSpawnPosition(Vector3 position)
|
||||
{
|
||||
// Use OverlapCircle to check for collisions with tiles
|
||||
Collider2D collision = Physics2D.OverlapCircle(position, spawnCollisionRadius, tileLayerMask);
|
||||
Collider2D collision = Physics2D.OverlapCircle(position, _settings.EndlessDescenderObstacleSpawnCollisionRadius, _devSettings.ObstacleTileLayerMask);
|
||||
return collision == null;
|
||||
}
|
||||
|
||||
@@ -330,7 +323,7 @@ namespace Minigames.DivingForPictures
|
||||
GameObject obstacle;
|
||||
|
||||
// Spawn using pool or instantiate directly
|
||||
if (useObjectPooling && _obstaclePool != null)
|
||||
if (_devSettings.ObstacleUseObjectPooling && _obstaclePool != null)
|
||||
{
|
||||
Debug.Log($"[ObstacleSpawner] Requesting obstacle from pool (prefab index {prefabIndex})");
|
||||
obstacle = _obstaclePool.GetObstacle(prefabIndex);
|
||||
@@ -416,8 +409,10 @@ namespace Minigames.DivingForPictures
|
||||
// Set prefab index
|
||||
obstacleComponent.PrefabIndex = prefabIndex;
|
||||
|
||||
// Randomize properties
|
||||
obstacleComponent.MoveSpeed = Random.Range(minMoveSpeed, maxMoveSpeed);
|
||||
// Randomize properties using settings
|
||||
obstacleComponent.MoveSpeed = Random.Range(
|
||||
_settings.EndlessDescenderObstacleMinMoveSpeed,
|
||||
_settings.EndlessDescenderObstacleMaxMoveSpeed);
|
||||
|
||||
// Set spawner reference (since FloatingObstacle has this built-in now)
|
||||
obstacleComponent.SetSpawner(this);
|
||||
@@ -440,7 +435,7 @@ namespace Minigames.DivingForPictures
|
||||
onObstacleDestroyed?.Invoke(obstacle);
|
||||
|
||||
// Return to pool or destroy
|
||||
if (useObjectPooling && _obstaclePool != null)
|
||||
if (_devSettings.ObstacleUseObjectPooling && _obstaclePool != null)
|
||||
{
|
||||
Debug.Log($"[ObstacleSpawner] Returning {obstacle.name} to pool");
|
||||
_obstaclePool.ReturnObstacle(obstacle, prefabIndex);
|
||||
@@ -457,7 +452,9 @@ namespace Minigames.DivingForPictures
|
||||
/// </summary>
|
||||
public void SetSpawnInterval(float interval)
|
||||
{
|
||||
spawnInterval = interval;
|
||||
// This method can no longer directly modify the settings
|
||||
// Consider implementing a runtime settings override system if needed
|
||||
Debug.LogWarning("[ObstacleSpawner] SetSpawnInterval no longer modifies settings directly. Settings are now centralized.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -465,8 +462,9 @@ namespace Minigames.DivingForPictures
|
||||
/// </summary>
|
||||
public void SetSpeedRange(float min, float max)
|
||||
{
|
||||
minMoveSpeed = min;
|
||||
maxMoveSpeed = max;
|
||||
// This method can no longer directly modify the settings
|
||||
// Consider implementing a runtime settings override system if needed
|
||||
Debug.LogWarning("[ObstacleSpawner] SetSpeedRange no longer modifies settings directly. Settings are now centralized.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -534,8 +532,8 @@ namespace Minigames.DivingForPictures
|
||||
#if UNITY_EDITOR
|
||||
private void OnDrawGizmosSelected()
|
||||
{
|
||||
// Only draw if screen bounds have been calculated
|
||||
if (_spawnRangeX > 0f)
|
||||
// Only draw if screen bounds have been calculated and settings are available
|
||||
if (_spawnRangeX > 0f && _settings != null)
|
||||
{
|
||||
// Draw spawn area using dynamic calculations
|
||||
Gizmos.color = Color.yellow;
|
||||
@@ -545,7 +543,7 @@ namespace Minigames.DivingForPictures
|
||||
|
||||
// Draw collision radius at spawn point
|
||||
Gizmos.color = Color.red;
|
||||
Gizmos.DrawWireSphere(center, spawnCollisionRadius);
|
||||
Gizmos.DrawWireSphere(center, _settings.EndlessDescenderObstacleSpawnCollisionRadius);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user