Update bird pooper speed discrepancy
This commit is contained in:
@@ -15,12 +15,22 @@ namespace Minigames.BirdPooper
|
|||||||
public UnityEngine.Events.UnityEvent OnFlap;
|
public UnityEngine.Events.UnityEvent OnFlap;
|
||||||
public UnityEngine.Events.UnityEvent OnPlayerDamaged;
|
public UnityEngine.Events.UnityEvent OnPlayerDamaged;
|
||||||
|
|
||||||
|
[Header("Flap Cooldown")]
|
||||||
|
[Tooltip("Minimum seconds between flaps to prevent multi-tap issues on mobile")]
|
||||||
|
[SerializeField] private float flapCooldown = 0.15f;
|
||||||
|
|
||||||
private Rigidbody2D _rb;
|
private Rigidbody2D _rb;
|
||||||
private IBirdPooperSettings _settings;
|
private IBirdPooperSettings _settings;
|
||||||
private float _verticalVelocity;
|
private float _verticalVelocity;
|
||||||
private bool _isDead;
|
private bool _isDead;
|
||||||
private float _fixedXPosition; // Store the initial X position from the scene
|
private float _fixedXPosition; // Store the initial X position from the scene
|
||||||
private bool _isInitialized; // Flag to control when physics/input are active
|
private bool _isInitialized; // Flag to control when physics/input are active
|
||||||
|
private float _lastFlapTime = -Mathf.Infinity; // Track last flap time for cooldown
|
||||||
|
|
||||||
|
// Diagnostic tracking
|
||||||
|
private int _updateFrameCount = 0;
|
||||||
|
private float _maxDeltaTime = 0f;
|
||||||
|
private float _minDeltaTime = float.MaxValue;
|
||||||
|
|
||||||
internal override void OnManagedAwake()
|
internal override void OnManagedAwake()
|
||||||
{
|
{
|
||||||
@@ -86,17 +96,44 @@ namespace Minigames.BirdPooper
|
|||||||
}
|
}
|
||||||
|
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
Debug.Log($"[BirdPlayerController] Initialized! Fixed X position: {_fixedXPosition}");
|
|
||||||
|
// DIAGNOSTIC: Log all critical values that might differ between platforms
|
||||||
|
Debug.Log($"[BirdPlayerController] ===== INITIALIZATION DIAGNOSTICS =====");
|
||||||
|
Debug.Log($"[BirdPlayerController] Fixed X position: {_fixedXPosition}");
|
||||||
|
Debug.Log($"[BirdPlayerController] Time.timeScale: {Time.timeScale}");
|
||||||
|
Debug.Log($"[BirdPlayerController] Application.targetFrameRate: {Application.targetFrameRate}");
|
||||||
|
Debug.Log($"[BirdPlayerController] Settings.Gravity: {_settings.Gravity}");
|
||||||
|
Debug.Log($"[BirdPlayerController] Settings.FlapForce: {_settings.FlapForce}");
|
||||||
|
Debug.Log($"[BirdPlayerController] Settings.MaxFallSpeed: {_settings.MaxFallSpeed}");
|
||||||
|
Debug.Log($"[BirdPlayerController] Settings.MinY: {_settings.MinY}");
|
||||||
|
Debug.Log($"[BirdPlayerController] Settings.MaxY: {_settings.MaxY}");
|
||||||
|
Debug.Log($"[BirdPlayerController] ==========================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Update()
|
/// <summary>
|
||||||
|
/// Using FixedUpdate for physics to ensure frame-rate independence.
|
||||||
|
/// FixedUpdate runs at a fixed timestep (default 0.02s = 50fps) regardless of actual frame rate.
|
||||||
|
/// </summary>
|
||||||
|
private void FixedUpdate()
|
||||||
{
|
{
|
||||||
// Only run physics/movement if initialized
|
// Only run physics/movement if initialized
|
||||||
if (!_isInitialized || _isDead || _settings == null || _rb == null)
|
if (!_isInitialized || _isDead || _settings == null || _rb == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Apply manual gravity
|
// DIAGNOSTIC: Track fixedDeltaTime (should be consistent)
|
||||||
_verticalVelocity -= _settings.Gravity * Time.deltaTime;
|
_updateFrameCount++;
|
||||||
|
float dt = Time.fixedDeltaTime;
|
||||||
|
if (dt > _maxDeltaTime) _maxDeltaTime = dt;
|
||||||
|
if (dt < _minDeltaTime) _minDeltaTime = dt;
|
||||||
|
|
||||||
|
// Log diagnostics every 50 fixed frames (every second at 50fps fixed timestep)
|
||||||
|
if (_updateFrameCount % 50 == 0)
|
||||||
|
{
|
||||||
|
Debug.Log($"[BirdPlayerController] FixedFrame {_updateFrameCount}: fixedDeltaTime={dt:F4}, min={_minDeltaTime:F4}, max={_maxDeltaTime:F4}, velocity={_verticalVelocity:F2}, pos.y={_rb.position.y:F2}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply manual gravity using fixedDeltaTime for consistent physics
|
||||||
|
_verticalVelocity -= _settings.Gravity * dt;
|
||||||
|
|
||||||
// Cap fall speed (terminal velocity)
|
// Cap fall speed (terminal velocity)
|
||||||
if (_verticalVelocity < -_settings.MaxFallSpeed)
|
if (_verticalVelocity < -_settings.MaxFallSpeed)
|
||||||
@@ -104,15 +141,26 @@ namespace Minigames.BirdPooper
|
|||||||
|
|
||||||
// Update position manually
|
// Update position manually
|
||||||
Vector2 newPosition = _rb.position;
|
Vector2 newPosition = _rb.position;
|
||||||
newPosition.y += _verticalVelocity * Time.deltaTime;
|
newPosition.y += _verticalVelocity * dt;
|
||||||
newPosition.x = _fixedXPosition; // Keep X fixed at scene-configured position
|
newPosition.x = _fixedXPosition; // Keep X fixed at scene-configured position
|
||||||
|
|
||||||
// Clamp Y position to bounds
|
// Clamp Y position to bounds
|
||||||
newPosition.y = Mathf.Clamp(newPosition.y, _settings.MinY, _settings.MaxY);
|
newPosition.y = Mathf.Clamp(newPosition.y, _settings.MinY, _settings.MaxY);
|
||||||
|
|
||||||
_rb.MovePosition(newPosition);
|
_rb.MovePosition(newPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Update runs at actual frame rate for smooth visual updates like rotation.
|
||||||
|
/// Physics calculations moved to FixedUpdate for frame-rate independence.
|
||||||
|
/// </summary>
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
// Only update visuals if initialized
|
||||||
|
if (!_isInitialized || _isDead || _settings == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// Update rotation based on velocity
|
// Update rotation based on velocity (visual only, runs at frame rate for smoothness)
|
||||||
UpdateRotation();
|
UpdateRotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,14 +186,25 @@ namespace Minigames.BirdPooper
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Makes the bird flap, applying upward velocity.
|
/// Makes the bird flap, applying upward velocity.
|
||||||
/// Can be called by input system or externally (e.g., for first tap).
|
/// Can be called by input system or externally (e.g., for first tap).
|
||||||
|
/// Includes cooldown to prevent multi-tap issues on mobile devices.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Flap()
|
public void Flap()
|
||||||
{
|
{
|
||||||
if (!_isInitialized || _isDead || _settings == null)
|
if (!_isInitialized || _isDead || _settings == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Cooldown check to prevent multi-tap issues (especially on mobile touchscreens)
|
||||||
|
if (Time.time < _lastFlapTime + flapCooldown)
|
||||||
|
{
|
||||||
|
Debug.Log($"[BirdPlayerController] Flap rejected - on cooldown ({Time.time - _lastFlapTime:F3}s since last flap)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_verticalVelocity = _settings.FlapForce;
|
_verticalVelocity = _settings.FlapForce;
|
||||||
Debug.Log($"[BirdPlayerController] Flap! velocity = {_verticalVelocity}");
|
_lastFlapTime = Time.time;
|
||||||
|
|
||||||
|
// DIAGNOSTIC: Log flap details including time values
|
||||||
|
Debug.Log($"[BirdPlayerController] FLAP! velocity={_verticalVelocity}, Time.time={Time.time}, Time.deltaTime={Time.deltaTime}, Time.timeScale={Time.timeScale}");
|
||||||
|
|
||||||
// Emit flap event
|
// Emit flap event
|
||||||
OnFlap?.Invoke();
|
OnFlap?.Invoke();
|
||||||
|
|||||||
137
Assets/Scripts/Minigames/BirdPooper/BirdPooperDebugDisplay.cs
Normal file
137
Assets/Scripts/Minigames/BirdPooper/BirdPooperDebugDisplay.cs
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using TMPro;
|
||||||
|
|
||||||
|
namespace Minigames.BirdPooper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// On-screen debug display for Bird Pooper minigame diagnostics.
|
||||||
|
/// Shows critical values that might differ between PC and mobile platforms.
|
||||||
|
/// </summary>
|
||||||
|
public class BirdPooperDebugDisplay : MonoBehaviour
|
||||||
|
{
|
||||||
|
[Header("References")]
|
||||||
|
[SerializeField] private BirdPlayerController birdController;
|
||||||
|
[SerializeField] private TextMeshProUGUI debugText;
|
||||||
|
|
||||||
|
[Header("Settings")]
|
||||||
|
[SerializeField] private bool showDebugDisplay = true;
|
||||||
|
[SerializeField] private float updateInterval = 0.1f; // Update display every 0.1 seconds
|
||||||
|
|
||||||
|
private float _nextUpdateTime;
|
||||||
|
private int _frameCount;
|
||||||
|
private float _minDeltaTime = float.MaxValue;
|
||||||
|
private float _maxDeltaTime = 0f;
|
||||||
|
private float _avgDeltaTime;
|
||||||
|
private float _deltaTimeSum;
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
if (debugText == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[BirdPooperDebugDisplay] Debug text reference not assigned!");
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (birdController == null)
|
||||||
|
{
|
||||||
|
birdController = FindFirstObjectByType<BirdPlayerController>();
|
||||||
|
if (birdController == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("[BirdPooperDebugDisplay] Could not find BirdPlayerController!");
|
||||||
|
enabled = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debugText.gameObject.SetActive(showDebugDisplay);
|
||||||
|
_nextUpdateTime = Time.time + updateInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
if (!showDebugDisplay || debugText == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Track deltaTime statistics
|
||||||
|
_frameCount++;
|
||||||
|
_deltaTimeSum += Time.deltaTime;
|
||||||
|
if (Time.deltaTime < _minDeltaTime) _minDeltaTime = Time.deltaTime;
|
||||||
|
if (Time.deltaTime > _maxDeltaTime) _maxDeltaTime = Time.deltaTime;
|
||||||
|
_avgDeltaTime = _deltaTimeSum / _frameCount;
|
||||||
|
|
||||||
|
// Update display at specified interval
|
||||||
|
if (Time.time >= _nextUpdateTime)
|
||||||
|
{
|
||||||
|
UpdateDebugDisplay();
|
||||||
|
_nextUpdateTime = Time.time + updateInterval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateDebugDisplay()
|
||||||
|
{
|
||||||
|
if (debugText == null) return;
|
||||||
|
|
||||||
|
// Get settings from the bird controller via reflection (hacky but works for debug)
|
||||||
|
var settingsField = typeof(BirdPlayerController).GetField("_settings",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
var settings = settingsField?.GetValue(birdController) as Core.Settings.IBirdPooperSettings;
|
||||||
|
|
||||||
|
var velocityField = typeof(BirdPlayerController).GetField("_verticalVelocity",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
float velocity = velocityField != null ? (float)velocityField.GetValue(birdController) : 0f;
|
||||||
|
|
||||||
|
var rbField = typeof(BirdPlayerController).GetField("_rb",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||||
|
var rb = rbField?.GetValue(birdController) as Rigidbody2D;
|
||||||
|
|
||||||
|
// Calculate actual FPS
|
||||||
|
float fps = _avgDeltaTime > 0 ? 1f / _avgDeltaTime : 0f;
|
||||||
|
|
||||||
|
// Build debug string
|
||||||
|
string debugInfo = "<b>BIRD POOPER DEBUG</b>\n";
|
||||||
|
debugInfo += "───────────\n";
|
||||||
|
debugInfo += $"<b>PLATFORM:</b> {Application.platform}\n";
|
||||||
|
debugInfo += $"<b>TIME SCALE:</b> {Time.timeScale:F2}\n";
|
||||||
|
debugInfo += $"<b>TARGET FPS:</b> {Application.targetFrameRate}\n";
|
||||||
|
debugInfo += $"<b>ACTUAL FPS:</b> {fps:F1}\n";
|
||||||
|
debugInfo += "───────────\n";
|
||||||
|
debugInfo += $"<b>ΔTime:</b> {Time.deltaTime:F4}s\n";
|
||||||
|
debugInfo += $"<b>ΔTime Min:</b> {_minDeltaTime:F4}s\n";
|
||||||
|
debugInfo += $"<b>ΔTime Max:</b> {_maxDeltaTime:F4}s\n";
|
||||||
|
debugInfo += $"<b>ΔTime Avg:</b> {_avgDeltaTime:F4}s\n";
|
||||||
|
debugInfo += $"<color=yellow><b>Fixed ΔT:</b> {Time.fixedDeltaTime:F4}s</color>\n";
|
||||||
|
debugInfo += "───────────\n";
|
||||||
|
|
||||||
|
if (settings != null)
|
||||||
|
{
|
||||||
|
debugInfo += $"<b>Gravity:</b> {settings.Gravity}\n";
|
||||||
|
debugInfo += $"<b>Flap Force:</b> {settings.FlapForce}\n";
|
||||||
|
debugInfo += $"<b>Max Fall:</b> {settings.MaxFallSpeed}\n";
|
||||||
|
debugInfo += "───────────\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
debugInfo += $"<b>Velocity:</b> {velocity:F2}\n";
|
||||||
|
if (rb != null)
|
||||||
|
{
|
||||||
|
debugInfo += $"<b>Position Y:</b> {rb.position.y:F2}\n";
|
||||||
|
}
|
||||||
|
debugInfo += $"<b>Dead:</b> {birdController.IsDead}\n";
|
||||||
|
|
||||||
|
debugText.text = debugInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Toggle debug display visibility - can be called from UI button
|
||||||
|
/// </summary>
|
||||||
|
public void ToggleDisplay()
|
||||||
|
{
|
||||||
|
showDebugDisplay = !showDebugDisplay;
|
||||||
|
if (debugText != null)
|
||||||
|
{
|
||||||
|
debugText.gameObject.SetActive(showDebugDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 28d9dbe8309a4e1e8529953f5b400c0e
|
||||||
|
timeCreated: 1766062170
|
||||||
@@ -12,8 +12,8 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: e7d3f5b948b3454681fa573071bee978, type: 3}
|
m_Script: {fileID: 11500000, guid: e7d3f5b948b3454681fa573071bee978, type: 3}
|
||||||
m_Name: BirdPooperSettings
|
m_Name: BirdPooperSettings
|
||||||
m_EditorClassIdentifier: AppleHillsScripts::Core.Settings.BirdPooperSettings
|
m_EditorClassIdentifier: AppleHillsScripts::Core.Settings.BirdPooperSettings
|
||||||
gravity: 110
|
gravity: 75
|
||||||
flapForce: 55
|
flapForce: 25
|
||||||
maxFallSpeed: 120
|
maxFallSpeed: 120
|
||||||
minY: -15
|
minY: -15
|
||||||
maxY: 15
|
maxY: 15
|
||||||
|
|||||||
Reference in New Issue
Block a user