Compare commits

...

3 Commits

Author SHA1 Message Date
Michal Pikulski
328e8dea0a Finalize normalized movement settings 2025-10-07 09:42:59 +02:00
Michal Pikulski
348e982930 Use normalized movement settings 2025-10-07 09:28:41 +02:00
Michal Pikulski
413576701e Fix input switching bug, where input would not be registered to GameMode, if game was booted in correct orientation 2025-10-07 08:32:32 +02:00
9 changed files with 471 additions and 161 deletions

View File

@@ -314,6 +314,8 @@ LineRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -335,6 +337,7 @@ LineRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -569,19 +572,6 @@ MonoBehaviour:
m_EditorClassIdentifier:
obstaclePrefabs:
- {fileID: 4743746373562280435, guid: 315a624eb99600444a51bb1d37c51742, type: 3}
spawnInterval: 2
spawnIntervalVariation: 1
maxSpawnAttempts: 10
spawnCollisionRadius: 1
minMoveSpeed: 2
maxMoveSpeed: 4
useObjectPooling: 1
maxPerPrefabPoolSize: 15
totalMaxPoolSize: 30
tileLayerMask:
serializedVersion: 2
m_Bits: 576
obstacleLayer: 11
onObstacleSpawned:
m_PersistentCalls:
m_Calls: []
@@ -637,20 +627,10 @@ MonoBehaviour:
- {fileID: 8588568014006713718, guid: 7c45910be7187144b8d2af12ff772353, type: 3}
- {fileID: 2665121316138540107, guid: c0d4b6d8a3b9a2447b883a78c568826c, type: 3}
- {fileID: 827631101927032693, guid: 5d23561cb618e86409a2b7ccbf08e37d, type: 3}
baseSpawnProbability: 0.2
maxSpawnProbability: 0.5
probabilityIncreaseRate: 0.01
guaranteedSpawnTime: 10
spawnCooldown: 5
basePoints: 10
depthMultiplier: 2
playerRopes:
- {fileID: 1435210811}
- {fileID: 1062017697}
- {fileID: 173052728}
speedTransitionDuration: 2
surfacingSpeedFactor: 3
surfacingSpawnDelay: 3
surfacingTimeline: {fileID: 2064311130}
--- !u!4 &424805726
Transform:
@@ -705,6 +685,8 @@ SpriteRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -726,6 +708,7 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 622133659
m_SortingLayer: -1
m_SortingOrder: 0
@@ -829,6 +812,8 @@ SpriteRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -850,6 +835,7 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -916,8 +902,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d39dbaae819c4a128a11ca60fbbc98c9, type: 3}
m_Name:
m_EditorClassIdentifier:
tapMaxDistance: 0.05
tapDecelerationRate: 5
--- !u!114 &747976399
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -930,14 +914,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 9072050a53fc4b539f4f4716bab53c07, type: 3}
m_Name:
m_EditorClassIdentifier:
wobbleFrequency: 1.5
baseWobbleAmplitude: 8
speedToAmplitude: 2
maxRotationLimit: 45
verticalFrequency: 0.5
verticalAmplitude: 0.2
velocitySmoothing: 10
rotationSmoothing: 10
--- !u!114 &747976400
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -950,41 +926,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 8222f0e3aeeb4fc4975aaead6cf7afbe, type: 3}
m_Name:
m_EditorClassIdentifier:
damageImmunityDuration: 1
obstacleLayerMask:
serializedVersion: 2
m_Bits: 64
blockInputDuringImmunity: 0
playerCharacter: {fileID: 747976396}
playerController: {fileID: 747976398}
bumpMode: 0
bumpForce: 5
smoothMoveSpeed: 8
bumpCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 2
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
- serializedVersion: 3
time: 1
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0
outWeight: 0
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
blockInputDuringBump: 1
--- !u!114 &747976401
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -997,11 +940,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c9c18dbd013d42ae8c221e6205e4d49c, type: 3}
m_Name:
m_EditorClassIdentifier:
damageImmunityDuration: 1
obstacleLayerMask:
serializedVersion: 2
m_Bits: 2048
blockInputDuringImmunity: 0
playerCharacter: {fileID: 747976396}
playerController: {fileID: 747976398}
--- !u!60 &747976402
@@ -1109,9 +1047,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: d8ea29cc80524de8affe17b930cd75c1, type: 3}
m_Name:
m_EditorClassIdentifier:
damageBlinkColor: {r: 1, g: 0, b: 0, a: 1}
blinkRate: 0.15
damageColorAlpha: 0.7
targetSpriteRenderer: {fileID: 730962734}
--- !u!95 &747976405
Animator:
@@ -1250,20 +1185,6 @@ MonoBehaviour:
- {fileID: 8773148034285304506, guid: cba81aa25acbe564cb363782f87c988a, type: 3}
- {fileID: -5093844878195686178, guid: eb62213ffae1fa242bcf16e696d9324f, type: 3}
- {fileID: 8944853044452083345, guid: 4ad95f797558b28478685ca60bd90ff4, type: 3}
spawnInterval: 0.5
speedRange: {x: 0.5, y: 2}
scaleRange: {x: 0.8, y: 1.2}
wobbleSpeedRange: {x: 0.2, y: 1}
wobbleAmountRange: {x: 0.05, y: 0.15}
spawnXMin: -3.5
spawnXMax: 3.5
spawnY: -6.78
wobbleMinScale: 0.5
wobbleMaxScale: 1.2
useObjectPooling: 1
initialPoolSize: 10
maxPoolSize: 30
surfacingSpeedFactor: 0.5
--- !u!4 &1003335105
Transform:
m_ObjectHideFlags: 0
@@ -1356,6 +1277,8 @@ LineRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -1377,6 +1300,7 @@ LineRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -1644,7 +1568,6 @@ MonoBehaviour:
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_Version: 2
m_TaaSettings:
m_Quality: 3
m_FrameInfluence: 0.1
@@ -1652,6 +1575,7 @@ MonoBehaviour:
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0
m_Version: 2
--- !u!1 &1224833348
GameObject:
m_ObjectHideFlags: 0
@@ -1684,11 +1608,11 @@ RectTransform:
m_Children: []
m_Father: {fileID: 116234201}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 1}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -81, y: -76}
m_SizeDelta: {x: 245.4807, y: 78.4255}
m_Pivot: {x: 1, y: 1}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 200, y: -43}
m_SizeDelta: {x: 245.48071, y: 78.4255}
m_Pivot: {x: 0, y: 1}
--- !u!114 &1224833350
MonoBehaviour:
m_ObjectHideFlags: 0
@@ -1896,6 +1820,8 @@ LineRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -1917,6 +1843,7 @@ LineRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -2073,22 +2000,12 @@ MonoBehaviour:
- {fileID: 2956826569642009690, guid: 43ed47cbe958b9f46b462e2fca2382c5, type: 3}
- {fileID: 2956826569642009690, guid: 4f772f2aebd38b44ca31063d196c77c1, type: 3}
- {fileID: 2956826569642009690, guid: 7f7f10ca24a5afe46be797daea64111a, type: 3}
initialTileCount: 3
tileSpawnBuffer: 1
moveSpeed: 5
speedUpFactor: 0
speedUpInterval: 0
maxMoveSpeed: 12
useObjectPooling: 1
maxPerPrefabPoolSize: 3
totalMaxPoolSize: 25
onTileSpawned:
m_PersistentCalls:
m_Calls: []
onTileDestroyed:
m_PersistentCalls:
m_Calls: []
velocityCalculationInterval: 0.5
onLastTileLeft:
m_PersistentCalls:
m_Calls: []
@@ -2144,6 +2061,8 @@ SpriteRenderer:
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_ForceMeshLod: -1
m_MeshLodSelectionBias: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
@@ -2165,6 +2084,7 @@ SpriteRenderer:
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_GlobalIlluminationMeshLod: 0
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
@@ -2365,14 +2285,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 9072050a53fc4b539f4f4716bab53c07, type: 3}
m_Name:
m_EditorClassIdentifier:
wobbleFrequency: 1.5
baseWobbleAmplitude: 8
speedToAmplitude: 2
maxRotationLimit: 45
verticalFrequency: 0.5
verticalAmplitude: 0.5
velocitySmoothing: 10
rotationSmoothing: 10
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0

View File

@@ -64,6 +64,10 @@ namespace AppleHills.Core.Settings
[Tooltip("How long to continue spawning tiles after surfacing begins (seconds)")]
[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")]
[Tooltip("Initial number of tiles to create at start")]
[SerializeField] private int initialTileCount = 3;
@@ -71,17 +75,21 @@ namespace AppleHills.Core.Settings
[Tooltip("Buffer distance for spawning new tiles")]
[SerializeField] private float tileSpawnBuffer = 1f;
[Tooltip("Base movement speed for tiles")]
[SerializeField] private float moveSpeed = 3f;
[Tooltip("Base movement speed for tiles in screen units per second (normalized)")]
[SerializeField] private float normalizedTileMoveSpeed = 0.3f;
[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)")]
[SerializeField] private float speedUpInterval = 10f;
[Tooltip("Maximum movement speed allowed")]
[SerializeField] private float maxMoveSpeed = 12f;
[Tooltip("Maximum normalized movement speed allowed for tiles")]
[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)")]
[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")]
[SerializeField] private float obstacleSpawnCollisionRadius = 1f;
[Tooltip("Minimum movement speed for spawned obstacles")]
[SerializeField] private float obstacleMinMoveSpeed = 1f;
[Tooltip("Minimum normalized movement speed for obstacles (screen units per second)")]
[SerializeField] private float normalizedObstacleMinMoveSpeed = 0.1f;
[Tooltip("Maximum movement speed for spawned obstacles")]
[SerializeField] private float obstacleMaxMoveSpeed = 4f;
[Tooltip("Maximum normalized movement speed for obstacles (screen units per second)")]
[SerializeField] private float normalizedObstacleMaxMoveSpeed = 0.4f;
[Header("Collision Handling")]
[Tooltip("Duration in seconds of damage immunity after being hit")]
@@ -148,10 +156,11 @@ namespace AppleHills.Core.Settings
// IDivingMinigameSettings implementation - Tile Generation
public int InitialTileCount => initialTileCount;
public float TileSpawnBuffer => tileSpawnBuffer;
public float MoveSpeed => moveSpeed;
public float ReferenceScreenHeight => referenceScreenHeight;
public float NormalizedMoveSpeed => normalizedTileMoveSpeed;
public float SpeedUpFactor => speedUpFactor;
public float SpeedUpInterval => speedUpInterval;
public float MaxMoveSpeed => maxMoveSpeed;
public float MaxNormalizedMoveSpeed => maxNormalizedTileMoveSpeed;
public float VelocityCalculationInterval => velocityCalculationInterval;
// IDivingMinigameSettings implementation - Obstacles
@@ -159,8 +168,8 @@ namespace AppleHills.Core.Settings
public float ObstacleSpawnIntervalVariation => obstacleSpawnIntervalVariation;
public int ObstacleMaxSpawnAttempts => obstacleMaxSpawnAttempts;
public float ObstacleSpawnCollisionRadius => obstacleSpawnCollisionRadius;
public float ObstacleMinMoveSpeed => obstacleMinMoveSpeed;
public float ObstacleMaxMoveSpeed => obstacleMaxMoveSpeed;
public float ObstacleMinMoveSpeed => normalizedObstacleMinMoveSpeed;
public float ObstacleMaxMoveSpeed => normalizedObstacleMaxMoveSpeed;
// IDivingMinigameSettings implementation - Collision Handling
public float DamageImmunityDuration => damageImmunityDuration;
@@ -211,10 +220,10 @@ namespace AppleHills.Core.Settings
// Validate tile generation
initialTileCount = Mathf.Max(1, initialTileCount);
tileSpawnBuffer = Mathf.Max(0f, tileSpawnBuffer);
moveSpeed = Mathf.Max(0.1f, moveSpeed);
normalizedTileMoveSpeed = Mathf.Max(0.01f, normalizedTileMoveSpeed);
speedUpFactor = Mathf.Max(0f, speedUpFactor);
speedUpInterval = Mathf.Max(0.1f, speedUpInterval);
maxMoveSpeed = Mathf.Max(moveSpeed, maxMoveSpeed);
maxNormalizedTileMoveSpeed = Mathf.Max(normalizedTileMoveSpeed, maxNormalizedTileMoveSpeed);
velocityCalculationInterval = Mathf.Max(0.01f, velocityCalculationInterval);
// Validate obstacle values
@@ -222,8 +231,8 @@ namespace AppleHills.Core.Settings
obstacleSpawnIntervalVariation = Mathf.Max(0f, obstacleSpawnIntervalVariation);
obstacleMaxSpawnAttempts = Mathf.Max(1, obstacleMaxSpawnAttempts);
obstacleSpawnCollisionRadius = Mathf.Max(0.1f, obstacleSpawnCollisionRadius);
obstacleMinMoveSpeed = Mathf.Max(0.1f, obstacleMinMoveSpeed);
obstacleMaxMoveSpeed = Mathf.Max(obstacleMinMoveSpeed, obstacleMaxMoveSpeed);
normalizedObstacleMinMoveSpeed = Mathf.Max(0.1f, normalizedObstacleMinMoveSpeed);
normalizedObstacleMaxMoveSpeed = Mathf.Max(normalizedObstacleMinMoveSpeed, normalizedObstacleMaxMoveSpeed);
// Validate collision settings
damageImmunityDuration = Mathf.Max(0.1f, damageImmunityDuration);

View File

@@ -79,19 +79,24 @@ namespace AppleHills.Core.Settings
// Tile Generation
int InitialTileCount { get; }
float TileSpawnBuffer { get; }
float MoveSpeed { get; }
float SpeedUpFactor { get; }
float SpeedUpInterval { get; }
float MaxMoveSpeed { 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
float ObstacleSpawnInterval { get; }
float ObstacleSpawnIntervalVariation { get; }
int ObstacleMaxSpawnAttempts { get; }
float ObstacleSpawnCollisionRadius { get; }
float ObstacleMinMoveSpeed { get; }
float ObstacleMaxMoveSpeed { get; }
float ObstacleMinMoveSpeed { get; } // Gets normalizedObstacleMinMoveSpeed
float ObstacleMaxMoveSpeed { get; } // Gets normalizedObstacleMaxMoveSpeed
// Collision Handling
float DamageImmunityDuration { get; }

View File

@@ -68,7 +68,7 @@ namespace Input
private void Start()
{
SceneManagerService.Instance.SceneLoadCompleted += SwitchInputOnSceneLoaded;
// SceneManagerService.Instance.SceneLoadCompleted += SwitchInputOnSceneLoaded;
SwitchInputOnSceneLoaded(SceneManager.GetActiveScene().name);
}

View File

@@ -1,6 +1,8 @@
using UnityEngine;
using System.Collections;
using AppleHills.Core.Settings;
using Pooling;
using Utils;
namespace Minigames.DivingForPictures
{
@@ -16,7 +18,7 @@ namespace Minigames.DivingForPictures
[Tooltip("Index of the prefab this obstacle was created from")]
[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;
[Header("Movement")]
@@ -51,6 +53,10 @@ namespace Minigames.DivingForPictures
private float _velocityFactor = 1.0f; // Current velocity factor from game manager
private float _baseMoveSpeed; // Original move speed before velocity factor is applied
// Screen normalization
private float _screenNormalizationFactor = 1.0f;
private IDivingMinigameSettings _settings;
private void Awake()
{
_collider = GetComponent<Collider2D>();
@@ -66,7 +72,45 @@ namespace Minigames.DivingForPictures
}
_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()
@@ -119,7 +163,7 @@ namespace Minigames.DivingForPictures
// Update actual move speed based on velocity factor and base speed
// 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
if (enableMovement && gameObject.activeInHierarchy)
@@ -131,19 +175,23 @@ namespace Minigames.DivingForPictures
_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>
/// Coroutine that handles obstacle movement
/// Coroutine that handles obstacle movement using normalized velocities
/// </summary>
private IEnumerator MovementCoroutine()
{
Debug.Log($"[FloatingObstacle] Started movement coroutine with speed: {_baseMoveSpeed:F3}");
while (enabled && gameObject.activeInHierarchy)
{
// Use velocity factor sign to determine direction
Vector3 direction = Vector3.up * Mathf.Sign(_velocityFactor);
float speed = moveSpeed * Time.deltaTime;
// Apply normalized movement using the shared utility method
float speed = AppleHillsUtils.CalculateNormalizedMovementSpeed(_baseMoveSpeed);
// Apply movement in correct direction
transform.position += direction * speed;

View File

@@ -5,6 +5,7 @@ using UnityEngine.Events;
using UnityEngine.Serialization;
using Pooling;
using AppleHills.Core.Settings;
using Utils;
namespace Minigames.DivingForPictures
{
@@ -56,6 +57,15 @@ namespace Minigames.DivingForPictures
// Velocity management
private float _baseMoveSpeed;
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()
{
@@ -75,7 +85,7 @@ namespace Minigames.DivingForPictures
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
CalculateTileHeights();
@@ -108,8 +118,6 @@ namespace Minigames.DivingForPictures
private void Start()
{
// Find DivingGameManager and subscribe to its initialization event
DivingGameManager gameManager = FindFirstObjectByType<DivingGameManager>();
if (gameManager != null)
@@ -136,23 +144,25 @@ namespace Minigames.DivingForPictures
/// </summary>
private void Initialize()
{
// Calculate screen bounds and normalization factor
CalculateScreenBounds();
CalculateScreenNormalizationFactor();
// Spawn initial tiles to fill the screen
SpawnInitialTiles();
// Initialize velocity and start the velocity calculation coroutine
_currentVelocity = _baseMoveSpeed * Time.fixedDeltaTime;
StartCoroutine(VelocityCalculationRoutine());
// Initialize velocity and apply screen normalization
_baseMoveSpeed = _settings?.NormalizedMoveSpeed ?? 3f;
_currentVelocity = _baseMoveSpeed * Time.fixedDeltaTime * _screenNormalizationFactor;
Debug.Log("[TrenchTileSpawner] Initialized");
}
private void Update()
{
HandleMovement();
HandleTileDestruction();
HandleTileSpawning();
HandleSpeedRamping();
// Start all coroutines
StartCoroutine(VelocityCalculationRoutine());
StartMovementCoroutine();
StartTileDestructionCoroutine();
StartTileSpawningCoroutine();
StartSpeedRampingCoroutine();
Debug.Log("[TrenchTileSpawner] Initialized with normalized speed");
}
/// <summary>
@@ -315,6 +325,24 @@ namespace Minigames.DivingForPictures
_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>
/// Called when the velocity factor changes from the DivingGameManager
/// </summary>
@@ -324,7 +352,7 @@ namespace Minigames.DivingForPictures
// Update the actual move speed based on the velocity factor
// 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
CalculateVelocity();
@@ -356,6 +384,55 @@ namespace Minigames.DivingForPictures
_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: {_baseMoveSpeed: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 using the shared utility method
float speed = AppleHillsUtils.CalculateNormalizedMovementSpeed(_baseMoveSpeed);
// 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>
/// Handles the movement of all active tiles based on the current velocity
/// </summary>
@@ -512,7 +589,7 @@ namespace Minigames.DivingForPictures
_speedUpTimer += Time.deltaTime;
if (_speedUpTimer >= _settings.SpeedUpInterval)
{
_baseMoveSpeed = Mathf.Min(_baseMoveSpeed + _settings.SpeedUpFactor, _settings.MaxMoveSpeed);
_baseMoveSpeed = Mathf.Min(_baseMoveSpeed + _settings.SpeedUpFactor, _settings.MaxNormalizedMoveSpeed);
_speedUpTimer = 0f;
}
}
@@ -739,5 +816,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);
}
}
}
}

View File

@@ -71,6 +71,11 @@ namespace Utility
ShowPrompt();
orientationCheckCoroutine = StartCoroutine(OrientationCheckRoutine());
}
else
{
orientationCorrect = true;
OnOrientationCorrect?.Invoke();
}
}
private bool IsMainMenuScene(Scene scene)

View File

@@ -1,9 +1,10 @@
using UnityEngine;
using AppleHills.Core.Settings;
namespace Utils
{
/// <summary>
/// Utility methods for working with SpriteRenderers.
/// Utility methods for working with SpriteRenderers and game mechanics.
/// </summary>
public static class AppleHillsUtils
{
@@ -28,5 +29,43 @@ namespace Utils
to.enabled = true;
to.transform.localScale = from.transform.localScale;
}
/// <summary>
/// Calculates a normalized movement speed value that's consistent across different screen sizes
/// and applies the current time delta
/// </summary>
/// <param name="normalizedSpeed">The base normalized speed value</param>
/// <returns>The actual movement amount to apply per frame</returns>
public static float CalculateNormalizedMovementSpeed(float normalizedSpeed)
{
// Get settings for reference height
var settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
if (settings == null)
{
Debug.LogWarning("[AppleHillsUtils] Could not get settings, using default reference height");
return CalculateNormalizedMovementSpeed(normalizedSpeed, 1080f);
}
return CalculateNormalizedMovementSpeed(normalizedSpeed, settings.ReferenceScreenHeight);
}
/// <summary>
/// Calculates a normalized movement speed value that's consistent across different screen sizes
/// and applies the current time delta
/// </summary>
/// <param name="normalizedSpeed">The base normalized speed value</param>
/// <param name="referenceScreenHeight">Reference screen height for normalization (typically 1080)</param>
/// <returns>The actual movement amount to apply per frame</returns>
public static float CalculateNormalizedMovementSpeed(float normalizedSpeed, float referenceScreenHeight)
{
// Calculate the screen normalization factor
float screenNormalizationFactor = Screen.height / referenceScreenHeight;
// Apply time delta for frame rate independence
float frameAdjustedSpeed = normalizedSpeed * Time.deltaTime;
// Apply screen normalization
return frameAdjustedSpeed * screenNormalizationFactor;
}
}
}

View File

@@ -29,19 +29,22 @@ MonoBehaviour:
speedTransitionDuration: 2
surfacingSpeedFactor: 3
surfacingSpawnDelay: 5
referenceScreenHeight: 1920
initialTileCount: 3
tileSpawnBuffer: 1
moveSpeed: 1
normalizedTileMoveSpeed: 2
speedUpFactor: 0
speedUpInterval: 10
maxNormalizedTileMoveSpeed: 2
moveSpeed: 1
maxMoveSpeed: 12
velocityCalculationInterval: 0.5
obstacleSpawnInterval: 2
obstacleSpawnIntervalVariation: 0.5
obstacleMaxSpawnAttempts: 10
obstacleSpawnCollisionRadius: 1
obstacleMinMoveSpeed: 1
obstacleMaxMoveSpeed: 4
normalizedObstacleMinMoveSpeed: 1
normalizedObstacleMaxMoveSpeed: 3
damageImmunityDuration: 1
bumpForce: 5
smoothMoveSpeed: 8