Use normalized movement settings
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
{"TestSuite":"","Date":0,"Player":{"Development":false,"ScreenWidth":0,"ScreenHeight":0,"ScreenRefreshRate":0,"Fullscreen":false,"Vsync":0,"AntiAliasing":0,"Batchmode":false,"RenderThreadingMode":"MultiThreaded","GpuSkinning":false,"Platform":"","ColorSpace":"","AnisotropicFiltering":"","BlendWeights":"","GraphicsApi":"","ScriptingBackend":"IL2CPP","AndroidTargetSdkVersion":"AndroidApiLevelAuto","AndroidBuildSystem":"Gradle","BuildTarget":"Android","StereoRenderingPath":"MultiPass"},"Hardware":{"OperatingSystem":"","DeviceModel":"","DeviceName":"","ProcessorType":"","ProcessorCount":0,"GraphicsDeviceName":"","SystemMemorySizeMB":0},"Editor":{"Version":"6000.2.6f1","Branch":"6000.2/staging","Changeset":"cc51a95c0300","Date":1758053328},"Dependencies":["com.unity.2d.sprite@1.0.0","com.unity.2d.spriteshape@12.0.1","com.unity.addressables@2.7.3","com.unity.addressables.android@1.0.7","com.unity.cinemachine@3.1.4","com.unity.feature.2d@2.0.1","com.unity.film-internal-utilities@0.18.4-preview","com.unity.graphtoolkit@0.4.0-exp.2","com.unity.ide.rider@3.0.38","com.unity.ide.visualstudio@2.0.23","com.unity.inputsystem@1.14.2","com.unity.multiplayer.center@1.0.0","com.unity.render-pipelines.universal@17.2.0","com.unity.timeline@1.8.9","com.unity.ugui@2.0.0","com.unity.modules.accessibility@1.0.0","com.unity.modules.ai@1.0.0","com.unity.modules.androidjni@1.0.0","com.unity.modules.animation@1.0.0","com.unity.modules.assetbundle@1.0.0","com.unity.modules.audio@1.0.0","com.unity.modules.cloth@1.0.0","com.unity.modules.director@1.0.0","com.unity.modules.imageconversion@1.0.0","com.unity.modules.imgui@1.0.0","com.unity.modules.jsonserialize@1.0.0","com.unity.modules.particlesystem@1.0.0","com.unity.modules.physics@1.0.0","com.unity.modules.physics2d@1.0.0","com.unity.modules.screencapture@1.0.0","com.unity.modules.terrain@1.0.0","com.unity.modules.terrainphysics@1.0.0","com.unity.modules.tilemap@1.0.0","com.unity.modules.ui@1.0.0","com.unity.modules.uielements@1.0.0","com.unity.modules.umbra@1.0.0","com.unity.modules.unityanalytics@1.0.0","com.unity.modules.unitywebrequest@1.0.0","com.unity.modules.unitywebrequestassetbundle@1.0.0","com.unity.modules.unitywebrequestaudio@1.0.0","com.unity.modules.unitywebrequesttexture@1.0.0","com.unity.modules.unitywebrequestwww@1.0.0","com.unity.modules.vehicles@1.0.0","com.unity.modules.video@1.0.0","com.unity.modules.vr@1.0.0","com.unity.modules.wind@1.0.0","com.unity.modules.xr@1.0.0","com.unity.modules.subsystems@1.0.0","com.unity.modules.hierarchycore@1.0.0","com.unity.render-pipelines.core@17.2.0","com.unity.shadergraph@17.2.0","com.unity.render-pipelines.universal-config@17.0.3","com.unity.test-framework@1.6.0","com.unity.ext.nunit@2.0.5","com.unity.2d.animation@12.0.2","com.unity.2d.pixel-perfect@5.1.0","com.unity.2d.psdimporter@11.0.1","com.unity.2d.tilemap@1.0.0","com.unity.2d.tilemap.extras@5.0.1","com.unity.2d.aseprite@2.0.1","com.unity.splines@2.8.2","com.unity.profiling.core@1.0.2","com.unity.scriptablebuildpipeline@2.4.2","com.unity.2d.common@11.0.1","com.unity.mathematics@1.3.2","com.unity.searcher@4.9.3","com.unity.burst@1.8.24","com.unity.collections@2.5.7","com.unity.rendering.light-transport@1.0.1","com.unity.settings-manager@2.1.0","com.unity.nuget.mono-cecil@1.11.5","com.unity.test-framework.performance@3.1.0"],"Results":[]}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"MeasurementCount":-1}
|
|
||||||
@@ -64,6 +64,10 @@ namespace AppleHills.Core.Settings
|
|||||||
[Tooltip("How long to continue spawning tiles after surfacing begins (seconds)")]
|
[Tooltip("How long to continue spawning tiles after surfacing begins (seconds)")]
|
||||||
[SerializeField] private float surfacingSpawnDelay = 5.0f;
|
[SerializeField] private float surfacingSpawnDelay = 5.0f;
|
||||||
|
|
||||||
|
[Header("Normalized Movement")]
|
||||||
|
[Tooltip("Reference screen height for normalized velocity calculations")]
|
||||||
|
[SerializeField] private float referenceScreenHeight = 1080f;
|
||||||
|
|
||||||
[Header("Tile Generation")]
|
[Header("Tile Generation")]
|
||||||
[Tooltip("Initial number of tiles to create at start")]
|
[Tooltip("Initial number of tiles to create at start")]
|
||||||
[SerializeField] private int initialTileCount = 3;
|
[SerializeField] private int initialTileCount = 3;
|
||||||
@@ -71,17 +75,21 @@ namespace AppleHills.Core.Settings
|
|||||||
[Tooltip("Buffer distance for spawning new tiles")]
|
[Tooltip("Buffer distance for spawning new tiles")]
|
||||||
[SerializeField] private float tileSpawnBuffer = 1f;
|
[SerializeField] private float tileSpawnBuffer = 1f;
|
||||||
|
|
||||||
[Tooltip("Base movement speed for tiles")]
|
[Tooltip("Base movement speed for tiles in screen units per second (normalized)")]
|
||||||
[SerializeField] private float moveSpeed = 3f;
|
[SerializeField] private float normalizedTileMoveSpeed = 0.3f;
|
||||||
|
|
||||||
[Tooltip("Factor to increase speed by each interval")]
|
[Tooltip("Factor to increase speed by each interval")]
|
||||||
[SerializeField] private float speedUpFactor = 0.2f;
|
[SerializeField] private float speedUpFactor = 0.05f;
|
||||||
|
|
||||||
[Tooltip("Time interval between speed increases (seconds)")]
|
[Tooltip("Time interval between speed increases (seconds)")]
|
||||||
[SerializeField] private float speedUpInterval = 10f;
|
[SerializeField] private float speedUpInterval = 10f;
|
||||||
|
|
||||||
[Tooltip("Maximum movement speed allowed")]
|
[Tooltip("Maximum normalized movement speed allowed for tiles")]
|
||||||
[SerializeField] private float maxMoveSpeed = 12f;
|
[SerializeField] private float maxNormalizedTileMoveSpeed = 1.2f;
|
||||||
|
|
||||||
|
// Legacy settings - keeping for backward compatibility
|
||||||
|
[HideInInspector] [SerializeField] private float moveSpeed = 3f;
|
||||||
|
[HideInInspector] [SerializeField] private float maxMoveSpeed = 12f;
|
||||||
|
|
||||||
[Tooltip("Interval for velocity calculations (seconds)")]
|
[Tooltip("Interval for velocity calculations (seconds)")]
|
||||||
[SerializeField] private float velocityCalculationInterval = 0.5f;
|
[SerializeField] private float velocityCalculationInterval = 0.5f;
|
||||||
@@ -99,11 +107,11 @@ namespace AppleHills.Core.Settings
|
|||||||
[Tooltip("Radius around obstacle spawn point to check for tile collisions")]
|
[Tooltip("Radius around obstacle spawn point to check for tile collisions")]
|
||||||
[SerializeField] private float obstacleSpawnCollisionRadius = 1f;
|
[SerializeField] private float obstacleSpawnCollisionRadius = 1f;
|
||||||
|
|
||||||
[Tooltip("Minimum movement speed for spawned obstacles")]
|
[Tooltip("Minimum normalized movement speed for obstacles (screen units per second)")]
|
||||||
[SerializeField] private float obstacleMinMoveSpeed = 1f;
|
[SerializeField] private float normalizedObstacleMinMoveSpeed = 0.1f;
|
||||||
|
|
||||||
[Tooltip("Maximum movement speed for spawned obstacles")]
|
[Tooltip("Maximum normalized movement speed for obstacles (screen units per second)")]
|
||||||
[SerializeField] private float obstacleMaxMoveSpeed = 4f;
|
[SerializeField] private float normalizedObstacleMaxMoveSpeed = 0.4f;
|
||||||
|
|
||||||
[Header("Collision Handling")]
|
[Header("Collision Handling")]
|
||||||
[Tooltip("Duration in seconds of damage immunity after being hit")]
|
[Tooltip("Duration in seconds of damage immunity after being hit")]
|
||||||
@@ -148,10 +156,11 @@ namespace AppleHills.Core.Settings
|
|||||||
// IDivingMinigameSettings implementation - Tile Generation
|
// IDivingMinigameSettings implementation - Tile Generation
|
||||||
public int InitialTileCount => initialTileCount;
|
public int InitialTileCount => initialTileCount;
|
||||||
public float TileSpawnBuffer => tileSpawnBuffer;
|
public float TileSpawnBuffer => tileSpawnBuffer;
|
||||||
public float MoveSpeed => moveSpeed;
|
public float ReferenceScreenHeight => referenceScreenHeight;
|
||||||
|
public float NormalizedMoveSpeed => normalizedTileMoveSpeed;
|
||||||
public float SpeedUpFactor => speedUpFactor;
|
public float SpeedUpFactor => speedUpFactor;
|
||||||
public float SpeedUpInterval => speedUpInterval;
|
public float SpeedUpInterval => speedUpInterval;
|
||||||
public float MaxMoveSpeed => maxMoveSpeed;
|
public float MaxNormalizedMoveSpeed => maxNormalizedTileMoveSpeed;
|
||||||
public float VelocityCalculationInterval => velocityCalculationInterval;
|
public float VelocityCalculationInterval => velocityCalculationInterval;
|
||||||
|
|
||||||
// IDivingMinigameSettings implementation - Obstacles
|
// IDivingMinigameSettings implementation - Obstacles
|
||||||
@@ -159,8 +168,8 @@ namespace AppleHills.Core.Settings
|
|||||||
public float ObstacleSpawnIntervalVariation => obstacleSpawnIntervalVariation;
|
public float ObstacleSpawnIntervalVariation => obstacleSpawnIntervalVariation;
|
||||||
public int ObstacleMaxSpawnAttempts => obstacleMaxSpawnAttempts;
|
public int ObstacleMaxSpawnAttempts => obstacleMaxSpawnAttempts;
|
||||||
public float ObstacleSpawnCollisionRadius => obstacleSpawnCollisionRadius;
|
public float ObstacleSpawnCollisionRadius => obstacleSpawnCollisionRadius;
|
||||||
public float ObstacleMinMoveSpeed => obstacleMinMoveSpeed;
|
public float ObstacleMinMoveSpeed => normalizedObstacleMinMoveSpeed;
|
||||||
public float ObstacleMaxMoveSpeed => obstacleMaxMoveSpeed;
|
public float ObstacleMaxMoveSpeed => normalizedObstacleMaxMoveSpeed;
|
||||||
|
|
||||||
// IDivingMinigameSettings implementation - Collision Handling
|
// IDivingMinigameSettings implementation - Collision Handling
|
||||||
public float DamageImmunityDuration => damageImmunityDuration;
|
public float DamageImmunityDuration => damageImmunityDuration;
|
||||||
@@ -211,10 +220,10 @@ namespace AppleHills.Core.Settings
|
|||||||
// Validate tile generation
|
// Validate tile generation
|
||||||
initialTileCount = Mathf.Max(1, initialTileCount);
|
initialTileCount = Mathf.Max(1, initialTileCount);
|
||||||
tileSpawnBuffer = Mathf.Max(0f, tileSpawnBuffer);
|
tileSpawnBuffer = Mathf.Max(0f, tileSpawnBuffer);
|
||||||
moveSpeed = Mathf.Max(0.1f, moveSpeed);
|
normalizedTileMoveSpeed = Mathf.Max(0.01f, normalizedTileMoveSpeed);
|
||||||
speedUpFactor = Mathf.Max(0f, speedUpFactor);
|
speedUpFactor = Mathf.Max(0f, speedUpFactor);
|
||||||
speedUpInterval = Mathf.Max(0.1f, speedUpInterval);
|
speedUpInterval = Mathf.Max(0.1f, speedUpInterval);
|
||||||
maxMoveSpeed = Mathf.Max(moveSpeed, maxMoveSpeed);
|
maxNormalizedTileMoveSpeed = Mathf.Max(normalizedTileMoveSpeed, maxNormalizedTileMoveSpeed);
|
||||||
velocityCalculationInterval = Mathf.Max(0.01f, velocityCalculationInterval);
|
velocityCalculationInterval = Mathf.Max(0.01f, velocityCalculationInterval);
|
||||||
|
|
||||||
// Validate obstacle values
|
// Validate obstacle values
|
||||||
@@ -222,8 +231,8 @@ namespace AppleHills.Core.Settings
|
|||||||
obstacleSpawnIntervalVariation = Mathf.Max(0f, obstacleSpawnIntervalVariation);
|
obstacleSpawnIntervalVariation = Mathf.Max(0f, obstacleSpawnIntervalVariation);
|
||||||
obstacleMaxSpawnAttempts = Mathf.Max(1, obstacleMaxSpawnAttempts);
|
obstacleMaxSpawnAttempts = Mathf.Max(1, obstacleMaxSpawnAttempts);
|
||||||
obstacleSpawnCollisionRadius = Mathf.Max(0.1f, obstacleSpawnCollisionRadius);
|
obstacleSpawnCollisionRadius = Mathf.Max(0.1f, obstacleSpawnCollisionRadius);
|
||||||
obstacleMinMoveSpeed = Mathf.Max(0.1f, obstacleMinMoveSpeed);
|
normalizedObstacleMinMoveSpeed = Mathf.Max(0.1f, normalizedObstacleMinMoveSpeed);
|
||||||
obstacleMaxMoveSpeed = Mathf.Max(obstacleMinMoveSpeed, obstacleMaxMoveSpeed);
|
normalizedObstacleMaxMoveSpeed = Mathf.Max(normalizedObstacleMinMoveSpeed, normalizedObstacleMaxMoveSpeed);
|
||||||
|
|
||||||
// Validate collision settings
|
// Validate collision settings
|
||||||
damageImmunityDuration = Mathf.Max(0.1f, damageImmunityDuration);
|
damageImmunityDuration = Mathf.Max(0.1f, damageImmunityDuration);
|
||||||
|
|||||||
@@ -79,19 +79,24 @@ namespace AppleHills.Core.Settings
|
|||||||
// Tile Generation
|
// Tile Generation
|
||||||
int InitialTileCount { get; }
|
int InitialTileCount { get; }
|
||||||
float TileSpawnBuffer { get; }
|
float TileSpawnBuffer { get; }
|
||||||
float MoveSpeed { get; }
|
|
||||||
float SpeedUpFactor { get; }
|
float SpeedUpFactor { get; }
|
||||||
float SpeedUpInterval { get; }
|
float SpeedUpInterval { get; }
|
||||||
float MaxMoveSpeed { get; }
|
|
||||||
float VelocityCalculationInterval { get; }
|
float VelocityCalculationInterval { get; }
|
||||||
|
|
||||||
|
// Normalized Movement
|
||||||
|
float ReferenceScreenHeight { get; } // Screen height reference for normalized velocities
|
||||||
|
|
||||||
|
// Normalized Tile Movement
|
||||||
|
float NormalizedMoveSpeed { get; } // Gets normalizedTileMoveSpeed
|
||||||
|
float MaxNormalizedMoveSpeed { get; } // Gets maxNormalizedTileMoveSpeed
|
||||||
|
|
||||||
// Obstacles
|
// Obstacles
|
||||||
float ObstacleSpawnInterval { get; }
|
float ObstacleSpawnInterval { get; }
|
||||||
float ObstacleSpawnIntervalVariation { get; }
|
float ObstacleSpawnIntervalVariation { get; }
|
||||||
int ObstacleMaxSpawnAttempts { get; }
|
int ObstacleMaxSpawnAttempts { get; }
|
||||||
float ObstacleSpawnCollisionRadius { get; }
|
float ObstacleSpawnCollisionRadius { get; }
|
||||||
float ObstacleMinMoveSpeed { get; }
|
float ObstacleMinMoveSpeed { get; } // Gets normalizedObstacleMinMoveSpeed
|
||||||
float ObstacleMaxMoveSpeed { get; }
|
float ObstacleMaxMoveSpeed { get; } // Gets normalizedObstacleMaxMoveSpeed
|
||||||
|
|
||||||
// Collision Handling
|
// Collision Handling
|
||||||
float DamageImmunityDuration { get; }
|
float DamageImmunityDuration { get; }
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using AppleHills.Core.Settings;
|
||||||
using Pooling;
|
using Pooling;
|
||||||
|
|
||||||
namespace Minigames.DivingForPictures
|
namespace Minigames.DivingForPictures
|
||||||
@@ -16,7 +17,7 @@ namespace Minigames.DivingForPictures
|
|||||||
[Tooltip("Index of the prefab this obstacle was created from")]
|
[Tooltip("Index of the prefab this obstacle was created from")]
|
||||||
[SerializeField] private int prefabIndex;
|
[SerializeField] private int prefabIndex;
|
||||||
|
|
||||||
[Tooltip("Movement speed of this obstacle")]
|
[Tooltip("Movement speed of this obstacle (will be overridden by normalized settings)")]
|
||||||
[SerializeField] private float moveSpeed = 2f;
|
[SerializeField] private float moveSpeed = 2f;
|
||||||
|
|
||||||
[Header("Movement")]
|
[Header("Movement")]
|
||||||
@@ -51,6 +52,10 @@ namespace Minigames.DivingForPictures
|
|||||||
private float _velocityFactor = 1.0f; // Current velocity factor from game manager
|
private float _velocityFactor = 1.0f; // Current velocity factor from game manager
|
||||||
private float _baseMoveSpeed; // Original move speed before velocity factor is applied
|
private float _baseMoveSpeed; // Original move speed before velocity factor is applied
|
||||||
|
|
||||||
|
// Screen normalization
|
||||||
|
private float _screenNormalizationFactor = 1.0f;
|
||||||
|
private IDivingMinigameSettings _settings;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
_collider = GetComponent<Collider2D>();
|
_collider = GetComponent<Collider2D>();
|
||||||
@@ -66,7 +71,45 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
|
|
||||||
_mainCamera = Camera.main;
|
_mainCamera = Camera.main;
|
||||||
_baseMoveSpeed = moveSpeed; // Store original speed
|
|
||||||
|
// Get settings
|
||||||
|
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
|
||||||
|
if (_settings == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[FloatingObstacle] Could not retrieve settings, using default values");
|
||||||
|
_baseMoveSpeed = moveSpeed; // Use the serialized value as fallback
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Initialize with the obstacle-specific normalized speed settings
|
||||||
|
float minSpeed = _settings.ObstacleMinMoveSpeed;
|
||||||
|
float maxSpeed = _settings.ObstacleMaxMoveSpeed;
|
||||||
|
|
||||||
|
// For variety, randomly assign a speed between min and max
|
||||||
|
_baseMoveSpeed = Random.Range(minSpeed, maxSpeed);
|
||||||
|
Debug.Log($"[FloatingObstacle] Initialized with normalized speed: {_baseMoveSpeed} (range: {minSpeed}-{maxSpeed})");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate screen normalization factor
|
||||||
|
CalculateScreenNormalizationFactor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the screen normalization factor based on current screen height
|
||||||
|
/// </summary>
|
||||||
|
private void CalculateScreenNormalizationFactor()
|
||||||
|
{
|
||||||
|
// Get reference height from settings with fallback if not available
|
||||||
|
float referenceHeight = 1080f; // Default fallback value
|
||||||
|
|
||||||
|
if (_settings != null)
|
||||||
|
{
|
||||||
|
referenceHeight = _settings.ReferenceScreenHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate normalization factor based on screen height
|
||||||
|
_screenNormalizationFactor = Screen.height / referenceHeight;
|
||||||
|
Debug.Log($"[FloatingObstacle] Screen normalization factor: {_screenNormalizationFactor} (Screen height: {Screen.height}, Reference: {referenceHeight})");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEnable()
|
private void OnEnable()
|
||||||
@@ -119,7 +162,7 @@ namespace Minigames.DivingForPictures
|
|||||||
|
|
||||||
// Update actual move speed based on velocity factor and base speed
|
// Update actual move speed based on velocity factor and base speed
|
||||||
// We use Abs for magnitude and Sign for direction
|
// We use Abs for magnitude and Sign for direction
|
||||||
moveSpeed = _baseMoveSpeed * Mathf.Abs(_velocityFactor);
|
moveSpeed = _baseMoveSpeed * Mathf.Abs(_velocityFactor) * _screenNormalizationFactor;
|
||||||
|
|
||||||
// Restart movement with new speed if needed
|
// Restart movement with new speed if needed
|
||||||
if (enableMovement && gameObject.activeInHierarchy)
|
if (enableMovement && gameObject.activeInHierarchy)
|
||||||
@@ -131,18 +174,22 @@ namespace Minigames.DivingForPictures
|
|||||||
_movementCoroutine = StartCoroutine(MovementCoroutine());
|
_movementCoroutine = StartCoroutine(MovementCoroutine());
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug.Log($"[FloatingObstacle] {gameObject.name} velocity factor updated to {_velocityFactor:F2}, speed: {moveSpeed:F2}");
|
Debug.Log($"[FloatingObstacle] {gameObject.name} velocity factor updated to {_velocityFactor:F2}, normalized speed: {moveSpeed:F2}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Coroutine that handles obstacle movement
|
/// Coroutine that handles obstacle movement using normalized velocities
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private IEnumerator MovementCoroutine()
|
private IEnumerator MovementCoroutine()
|
||||||
{
|
{
|
||||||
|
Debug.Log($"[FloatingObstacle] Started movement coroutine with speed: {moveSpeed:F3}");
|
||||||
|
|
||||||
while (enabled && gameObject.activeInHierarchy)
|
while (enabled && gameObject.activeInHierarchy)
|
||||||
{
|
{
|
||||||
// Use velocity factor sign to determine direction
|
// Use velocity factor sign to determine direction
|
||||||
Vector3 direction = Vector3.up * Mathf.Sign(_velocityFactor);
|
Vector3 direction = Vector3.up * Mathf.Sign(_velocityFactor);
|
||||||
|
|
||||||
|
// Apply normalized movement with deltaTime for frame rate independence
|
||||||
float speed = moveSpeed * Time.deltaTime;
|
float speed = moveSpeed * Time.deltaTime;
|
||||||
|
|
||||||
// Apply movement in correct direction
|
// Apply movement in correct direction
|
||||||
|
|||||||
@@ -56,6 +56,15 @@ namespace Minigames.DivingForPictures
|
|||||||
// Velocity management
|
// Velocity management
|
||||||
private float _baseMoveSpeed;
|
private float _baseMoveSpeed;
|
||||||
private float _velocityFactor = 1.0f;
|
private float _velocityFactor = 1.0f;
|
||||||
|
|
||||||
|
// Coroutine references
|
||||||
|
private Coroutine _movementCoroutine;
|
||||||
|
private Coroutine _tileDestructionCoroutine;
|
||||||
|
private Coroutine _tileSpawningCoroutine;
|
||||||
|
private Coroutine _speedRampingCoroutine;
|
||||||
|
|
||||||
|
// Screen normalization
|
||||||
|
private float _screenNormalizationFactor = 1.0f;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
@@ -75,7 +84,7 @@ namespace Minigames.DivingForPictures
|
|||||||
Debug.LogError("[TrenchTileSpawner] Failed to load diving developer settings!");
|
Debug.LogError("[TrenchTileSpawner] Failed to load diving developer settings!");
|
||||||
}
|
}
|
||||||
|
|
||||||
_baseMoveSpeed = _settings?.MoveSpeed ?? 3f; // Store the original base speed
|
_baseMoveSpeed = _settings?.NormalizedMoveSpeed ?? 3f; // Store the original base speed
|
||||||
|
|
||||||
// Calculate tile heights for each prefab
|
// Calculate tile heights for each prefab
|
||||||
CalculateTileHeights();
|
CalculateTileHeights();
|
||||||
@@ -108,8 +117,6 @@ namespace Minigames.DivingForPictures
|
|||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Find DivingGameManager and subscribe to its initialization event
|
// Find DivingGameManager and subscribe to its initialization event
|
||||||
DivingGameManager gameManager = FindFirstObjectByType<DivingGameManager>();
|
DivingGameManager gameManager = FindFirstObjectByType<DivingGameManager>();
|
||||||
if (gameManager != null)
|
if (gameManager != null)
|
||||||
@@ -136,23 +143,25 @@ namespace Minigames.DivingForPictures
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void Initialize()
|
private void Initialize()
|
||||||
{
|
{
|
||||||
|
// Calculate screen bounds and normalization factor
|
||||||
CalculateScreenBounds();
|
CalculateScreenBounds();
|
||||||
|
CalculateScreenNormalizationFactor();
|
||||||
|
|
||||||
// Spawn initial tiles to fill the screen
|
// Spawn initial tiles to fill the screen
|
||||||
SpawnInitialTiles();
|
SpawnInitialTiles();
|
||||||
|
|
||||||
// Initialize velocity and start the velocity calculation coroutine
|
// Initialize velocity and apply screen normalization
|
||||||
_currentVelocity = _baseMoveSpeed * Time.fixedDeltaTime;
|
_baseMoveSpeed = _settings?.NormalizedMoveSpeed ?? 3f;
|
||||||
StartCoroutine(VelocityCalculationRoutine());
|
_currentVelocity = _baseMoveSpeed * Time.fixedDeltaTime * _screenNormalizationFactor;
|
||||||
|
|
||||||
Debug.Log("[TrenchTileSpawner] Initialized");
|
// Start all coroutines
|
||||||
}
|
StartCoroutine(VelocityCalculationRoutine());
|
||||||
|
StartMovementCoroutine();
|
||||||
private void Update()
|
StartTileDestructionCoroutine();
|
||||||
{
|
StartTileSpawningCoroutine();
|
||||||
HandleMovement();
|
StartSpeedRampingCoroutine();
|
||||||
HandleTileDestruction();
|
|
||||||
HandleTileSpawning();
|
Debug.Log("[TrenchTileSpawner] Initialized with normalized speed");
|
||||||
HandleSpeedRamping();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -315,6 +324,24 @@ namespace Minigames.DivingForPictures
|
|||||||
_screenTop = top.y;
|
_screenTop = top.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates the screen normalization factor based on current screen height
|
||||||
|
/// </summary>
|
||||||
|
private void CalculateScreenNormalizationFactor()
|
||||||
|
{
|
||||||
|
// Get reference height from settings with fallback if not available
|
||||||
|
float referenceHeight = 1080f; // Default fallback value
|
||||||
|
|
||||||
|
if (_settings != null)
|
||||||
|
{
|
||||||
|
referenceHeight = _settings.ReferenceScreenHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate normalization factor based on screen height
|
||||||
|
_screenNormalizationFactor = Screen.height / referenceHeight;
|
||||||
|
Debug.Log($"[TrenchTileSpawner] Screen normalization factor: {_screenNormalizationFactor} (Screen height: {Screen.height}, Reference: {referenceHeight})");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called when the velocity factor changes from the DivingGameManager
|
/// Called when the velocity factor changes from the DivingGameManager
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -324,7 +351,7 @@ namespace Minigames.DivingForPictures
|
|||||||
|
|
||||||
// Update the actual move speed based on the velocity factor
|
// Update the actual move speed based on the velocity factor
|
||||||
// This keeps the original move speed intact for game logic
|
// This keeps the original move speed intact for game logic
|
||||||
_baseMoveSpeed = _settings.MoveSpeed * Mathf.Abs(_velocityFactor);
|
_baseMoveSpeed = _settings.NormalizedMoveSpeed * Mathf.Abs(_velocityFactor);
|
||||||
|
|
||||||
// Recalculate velocity immediately
|
// Recalculate velocity immediately
|
||||||
CalculateVelocity();
|
CalculateVelocity();
|
||||||
@@ -356,6 +383,55 @@ namespace Minigames.DivingForPictures
|
|||||||
_stopSpawning = true;
|
_stopSpawning = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the movement coroutine and stores its reference
|
||||||
|
/// </summary>
|
||||||
|
private void StartMovementCoroutine()
|
||||||
|
{
|
||||||
|
if (_movementCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(_movementCoroutine);
|
||||||
|
}
|
||||||
|
_movementCoroutine = StartCoroutine(MovementCoroutine());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Coroutine that handles obstacle movement using normalized screen-relative speed
|
||||||
|
/// </summary>
|
||||||
|
private IEnumerator MovementCoroutine()
|
||||||
|
{
|
||||||
|
Debug.Log($"[TrenchTileSpawner] Started movement coroutine with normalized speed: {_currentVelocity:F3}");
|
||||||
|
|
||||||
|
while (enabled && gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
// Skip if no active tiles
|
||||||
|
if (_activeTiles.Count == 0)
|
||||||
|
{
|
||||||
|
yield return null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use velocity factor sign to determine direction
|
||||||
|
Vector3 direction = Vector3.up * Mathf.Sign(_velocityFactor);
|
||||||
|
|
||||||
|
// Apply normalized movement with deltaTime for frame rate independence
|
||||||
|
float speed = _currentVelocity * _screenNormalizationFactor;
|
||||||
|
|
||||||
|
// Move all active tiles
|
||||||
|
foreach (var tile in _activeTiles)
|
||||||
|
{
|
||||||
|
if (tile != null)
|
||||||
|
{
|
||||||
|
// Apply movement in correct direction
|
||||||
|
tile.transform.position += direction * speed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for next frame
|
||||||
|
yield return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the movement of all active tiles based on the current velocity
|
/// Handles the movement of all active tiles based on the current velocity
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -512,7 +588,7 @@ namespace Minigames.DivingForPictures
|
|||||||
_speedUpTimer += Time.deltaTime;
|
_speedUpTimer += Time.deltaTime;
|
||||||
if (_speedUpTimer >= _settings.SpeedUpInterval)
|
if (_speedUpTimer >= _settings.SpeedUpInterval)
|
||||||
{
|
{
|
||||||
_baseMoveSpeed = Mathf.Min(_baseMoveSpeed + _settings.SpeedUpFactor, _settings.MaxMoveSpeed);
|
_baseMoveSpeed = Mathf.Min(_baseMoveSpeed + _settings.SpeedUpFactor, _settings.MaxNormalizedMoveSpeed);
|
||||||
_speedUpTimer = 0f;
|
_speedUpTimer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -739,5 +815,217 @@ namespace Minigames.DivingForPictures
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the tile destruction coroutine and stores its reference
|
||||||
|
/// </summary>
|
||||||
|
private void StartTileDestructionCoroutine()
|
||||||
|
{
|
||||||
|
if (_tileDestructionCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(_tileDestructionCoroutine);
|
||||||
|
}
|
||||||
|
_tileDestructionCoroutine = StartCoroutine(TileDestructionCoroutine());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Coroutine that checks for tiles to destroy periodically
|
||||||
|
/// </summary>
|
||||||
|
private IEnumerator TileDestructionCoroutine()
|
||||||
|
{
|
||||||
|
const float checkInterval = 0.5f; // Check every half second as requested
|
||||||
|
Debug.Log($"[TrenchTileSpawner] Started tile destruction coroutine with interval: {checkInterval}s");
|
||||||
|
|
||||||
|
while (enabled && gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
// Check and handle tile destruction
|
||||||
|
if (_activeTiles.Count > 0)
|
||||||
|
{
|
||||||
|
GameObject topTile = _activeTiles[0];
|
||||||
|
if (topTile == null)
|
||||||
|
{
|
||||||
|
_activeTiles.RemoveAt(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float tileHeight = GetTileHeight(topTile);
|
||||||
|
|
||||||
|
bool shouldDestroy;
|
||||||
|
if (_isSurfacing)
|
||||||
|
{
|
||||||
|
// When surfacing, destroy tiles at the bottom
|
||||||
|
shouldDestroy = topTile.transform.position.y + tileHeight / 2 < _screenBottom - _settings.TileSpawnBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// When descending, destroy tiles at the top
|
||||||
|
shouldDestroy = topTile.transform.position.y - tileHeight / 2 > _screenTop + _settings.TileSpawnBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldDestroy)
|
||||||
|
{
|
||||||
|
_activeTiles.RemoveAt(0);
|
||||||
|
onTileDestroyed?.Invoke(topTile);
|
||||||
|
|
||||||
|
if (_devSettings != null && _devSettings.TrenchTileUseObjectPooling && _tilePool != null)
|
||||||
|
{
|
||||||
|
// Find the prefab index for this tile
|
||||||
|
int prefabIndex = GetPrefabIndex(topTile);
|
||||||
|
if (prefabIndex >= 0)
|
||||||
|
{
|
||||||
|
_tilePool.ReturnTile(topTile, prefabIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(topTile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Destroy(topTile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the next check interval
|
||||||
|
yield return new WaitForSeconds(checkInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the tile spawning coroutine and stores its reference
|
||||||
|
/// </summary>
|
||||||
|
private void StartTileSpawningCoroutine()
|
||||||
|
{
|
||||||
|
if (_tileSpawningCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(_tileSpawningCoroutine);
|
||||||
|
}
|
||||||
|
_tileSpawningCoroutine = StartCoroutine(TileSpawningCoroutine());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Coroutine that checks if new tiles need to be spawned periodically
|
||||||
|
/// </summary>
|
||||||
|
private IEnumerator TileSpawningCoroutine()
|
||||||
|
{
|
||||||
|
const float checkInterval = 0.2f; // Check every half second as requested
|
||||||
|
Debug.Log($"[TrenchTileSpawner] Started tile spawning coroutine with interval: {checkInterval}s");
|
||||||
|
|
||||||
|
while (enabled && gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
// Check if we need to spawn new tiles
|
||||||
|
if (_activeTiles.Count == 0)
|
||||||
|
{
|
||||||
|
// If we have no active tiles and spawning is stopped, trigger the event
|
||||||
|
if (_stopSpawning)
|
||||||
|
{
|
||||||
|
onLastTileLeft.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameObject bottomTile = _activeTiles[^1];
|
||||||
|
if (bottomTile == null)
|
||||||
|
{
|
||||||
|
_activeTiles.RemoveAt(_activeTiles.Count - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get the tile height once to use in all calculations
|
||||||
|
float tileHeight = GetTileHeight(bottomTile);
|
||||||
|
|
||||||
|
// If we're in stop spawning mode, check if last tile is leaving
|
||||||
|
if (_stopSpawning)
|
||||||
|
{
|
||||||
|
// Check if this is the last tile, and if it's about to leave the screen
|
||||||
|
if (_activeTiles.Count == 1)
|
||||||
|
{
|
||||||
|
bool isLastTileLeaving;
|
||||||
|
|
||||||
|
if (_isSurfacing)
|
||||||
|
{
|
||||||
|
// When surfacing, check if bottom of tile is above top of screen
|
||||||
|
isLastTileLeaving = bottomTile.transform.position.y - tileHeight / 2 > _screenTop + _settings.TileSpawnBuffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// When descending, check if top of tile is below bottom of screen
|
||||||
|
isLastTileLeaving = bottomTile.transform.position.y + tileHeight / 2 < _screenBottom - _settings.TileSpawnBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLastTileLeaving)
|
||||||
|
{
|
||||||
|
onLastTileLeft.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Normal spawning mode
|
||||||
|
bool shouldSpawn;
|
||||||
|
float newY;
|
||||||
|
|
||||||
|
if (_isSurfacing)
|
||||||
|
{
|
||||||
|
// When surfacing, spawn new tiles at the top
|
||||||
|
float topEdge = bottomTile.transform.position.y + tileHeight / 2;
|
||||||
|
shouldSpawn = topEdge < _screenTop + _settings.TileSpawnBuffer;
|
||||||
|
newY = bottomTile.transform.position.y + tileHeight;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// When descending, spawn new tiles at the bottom
|
||||||
|
float bottomEdge = bottomTile.transform.position.y - tileHeight / 2;
|
||||||
|
shouldSpawn = bottomEdge > _screenBottom - _settings.TileSpawnBuffer;
|
||||||
|
newY = bottomTile.transform.position.y - tileHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldSpawn)
|
||||||
|
{
|
||||||
|
SpawnTileAtY(newY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for the next check interval
|
||||||
|
yield return new WaitForSeconds(checkInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Starts the speed ramping coroutine and stores its reference
|
||||||
|
/// </summary>
|
||||||
|
private void StartSpeedRampingCoroutine()
|
||||||
|
{
|
||||||
|
if (_speedRampingCoroutine != null)
|
||||||
|
{
|
||||||
|
StopCoroutine(_speedRampingCoroutine);
|
||||||
|
}
|
||||||
|
_speedRampingCoroutine = StartCoroutine(SpeedRampingCoroutine());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Coroutine that handles increasing the movement speed over time
|
||||||
|
/// </summary>
|
||||||
|
private IEnumerator SpeedRampingCoroutine()
|
||||||
|
{
|
||||||
|
const float checkInterval = 1.0f; // Check once per second as requested
|
||||||
|
Debug.Log($"[TrenchTileSpawner] Started speed ramping coroutine with interval: {checkInterval}s");
|
||||||
|
|
||||||
|
while (enabled && gameObject.activeInHierarchy)
|
||||||
|
{
|
||||||
|
// Increase the base move speed up to the maximum
|
||||||
|
_baseMoveSpeed = Mathf.Min(_baseMoveSpeed + _settings.SpeedUpFactor, _settings.MaxNormalizedMoveSpeed);
|
||||||
|
|
||||||
|
// Recalculate velocity with the new base speed
|
||||||
|
CalculateVelocity();
|
||||||
|
|
||||||
|
// Wait for the next check interval
|
||||||
|
yield return new WaitForSeconds(checkInterval);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,19 +29,22 @@ MonoBehaviour:
|
|||||||
speedTransitionDuration: 2
|
speedTransitionDuration: 2
|
||||||
surfacingSpeedFactor: 3
|
surfacingSpeedFactor: 3
|
||||||
surfacingSpawnDelay: 5
|
surfacingSpawnDelay: 5
|
||||||
|
referenceScreenHeight: 1920
|
||||||
initialTileCount: 3
|
initialTileCount: 3
|
||||||
tileSpawnBuffer: 1
|
tileSpawnBuffer: 1
|
||||||
moveSpeed: 1
|
normalizedTileMoveSpeed: 0.5
|
||||||
speedUpFactor: 0
|
speedUpFactor: 0
|
||||||
speedUpInterval: 10
|
speedUpInterval: 10
|
||||||
|
maxNormalizedTileMoveSpeed: 0.5
|
||||||
|
moveSpeed: 1
|
||||||
maxMoveSpeed: 12
|
maxMoveSpeed: 12
|
||||||
velocityCalculationInterval: 0.5
|
velocityCalculationInterval: 0.5
|
||||||
obstacleSpawnInterval: 2
|
obstacleSpawnInterval: 2
|
||||||
obstacleSpawnIntervalVariation: 0.5
|
obstacleSpawnIntervalVariation: 0.5
|
||||||
obstacleMaxSpawnAttempts: 10
|
obstacleMaxSpawnAttempts: 10
|
||||||
obstacleSpawnCollisionRadius: 1
|
obstacleSpawnCollisionRadius: 1
|
||||||
obstacleMinMoveSpeed: 1
|
normalizedObstacleMinMoveSpeed: 1
|
||||||
obstacleMaxMoveSpeed: 4
|
normalizedObstacleMaxMoveSpeed: 2
|
||||||
damageImmunityDuration: 1
|
damageImmunityDuration: 1
|
||||||
bumpForce: 5
|
bumpForce: 5
|
||||||
smoothMoveSpeed: 8
|
smoothMoveSpeed: 8
|
||||||
|
|||||||
Reference in New Issue
Block a user