Working MVP code for Valentines
This commit is contained in:
committed by
Michal Pikulski
parent
ad8338f37e
commit
e9d528d837
@@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AppleHills.Core.Settings;
|
||||
using Common.Input;
|
||||
using Minigames.FortFight.Data;
|
||||
using Minigames.FortFight.Settings;
|
||||
using UnityEngine;
|
||||
@@ -14,6 +15,19 @@ namespace Minigames.FortFight.Core
|
||||
[CreateAssetMenu(fileName = "FortFightSettings", menuName = "AppleHills/Settings/Fort Fight", order = 8)]
|
||||
public class FortFightSettings : BaseSettings, IFortFightSettings
|
||||
{
|
||||
[Header("Slingshot Configuration")]
|
||||
[SerializeField] private SlingshotConfig slingshotSettings = new SlingshotConfig
|
||||
{
|
||||
maxDragDistance = 5f,
|
||||
baseLaunchForce = 20f,
|
||||
minForceMultiplier = 0.1f,
|
||||
maxForceMultiplier = 1f,
|
||||
trajectoryPoints = 50,
|
||||
trajectoryTimeStep = 0.1f,
|
||||
trajectoryLockDuration = 2f,
|
||||
autoRegisterInput = false // TurnManager handles registration
|
||||
};
|
||||
|
||||
[Header("Block Material Configurations")]
|
||||
[Tooltip("HP and mass configurations for each material type")]
|
||||
[SerializeField] private List<BlockMaterialConfig> materialConfigs = new List<BlockMaterialConfig>
|
||||
@@ -142,6 +156,8 @@ namespace Minigames.FortFight.Core
|
||||
|
||||
#region IFortFightSettings Implementation
|
||||
|
||||
public SlingshotConfig SlingshotSettings => slingshotSettings;
|
||||
|
||||
public List<BlockMaterialConfig> MaterialConfigs => materialConfigs;
|
||||
public List<BlockSizeConfig> SizeConfigs => sizeConfigs;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using AppleHills.Core.Settings;
|
||||
using Common.Input;
|
||||
using Core;
|
||||
using Core.Lifecycle;
|
||||
using Minigames.FortFight.Data;
|
||||
using Minigames.FortFight.Projectiles;
|
||||
using UnityEngine;
|
||||
@@ -9,22 +9,14 @@ using UnityEngine;
|
||||
namespace Minigames.FortFight.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Controls slingshot aiming and projectile launching.
|
||||
/// Angry Birds-style drag-to-aim mechanic with trajectory preview.
|
||||
/// Implements ITouchInputConsumer for InputManager integration.
|
||||
/// Controls slingshot aiming and projectile launching for FortFight.
|
||||
/// Extends DragLaunchController with FortFight-specific ammo management and trajectory preview.
|
||||
/// </summary>
|
||||
public class SlingshotController : ManagedBehaviour, ITouchInputConsumer
|
||||
public class SlingshotController : DragLaunchController
|
||||
{
|
||||
#region Inspector Properties
|
||||
|
||||
[Header("Launch Settings")]
|
||||
[Tooltip("Drag distance to reach max force")]
|
||||
[SerializeField] private float maxDragDistance = 5f;
|
||||
|
||||
[Tooltip("Spawn point for projectiles")]
|
||||
[SerializeField] private Transform projectileSpawnPoint;
|
||||
|
||||
[Header("References")]
|
||||
[Header("FortFight Specific")]
|
||||
[Tooltip("Trajectory preview component")]
|
||||
[SerializeField] private TrajectoryPreview trajectoryPreview;
|
||||
|
||||
@@ -58,8 +50,15 @@ namespace Minigames.FortFight.Core
|
||||
}
|
||||
}
|
||||
|
||||
private float MaxForce => CachedSettings?.BaseLaunchForce ?? 20f;
|
||||
private bool ShowDebugLogs => CachedDevSettings?.SlingshotShowDebugLogs ?? false;
|
||||
protected override SlingshotConfig GetSlingshotConfig()
|
||||
{
|
||||
return CachedSettings?.SlingshotSettings;
|
||||
}
|
||||
|
||||
protected override GameObject GetProjectilePrefab()
|
||||
{
|
||||
return _currentAmmo?.prefab;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -74,13 +73,10 @@ namespace Minigames.FortFight.Core
|
||||
|
||||
#region State
|
||||
|
||||
private bool _isDragging;
|
||||
private Vector2 _dragStartPosition;
|
||||
private ProjectileConfig _currentAmmo;
|
||||
private ProjectileBase _activeProjectile;
|
||||
|
||||
public bool IsDragging => _isDragging;
|
||||
public bool IsEnabled { get; private set; } = true;
|
||||
public ProjectileBase ActiveProjectile => _activeProjectile;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -90,15 +86,15 @@ namespace Minigames.FortFight.Core
|
||||
{
|
||||
base.OnManagedAwake();
|
||||
|
||||
if (projectileSpawnPoint == null)
|
||||
{
|
||||
projectileSpawnPoint = transform;
|
||||
}
|
||||
// Base class handles launchAnchor (previously projectileSpawnPoint)
|
||||
|
||||
if (trajectoryPreview == null)
|
||||
{
|
||||
trajectoryPreview = GetComponent<TrajectoryPreview>();
|
||||
}
|
||||
|
||||
// Set debug logging from developer settings
|
||||
showDebugLogs = CachedDevSettings?.SlingshotShowDebugLogs ?? false;
|
||||
}
|
||||
|
||||
internal override void OnManagedStart()
|
||||
@@ -114,132 +110,51 @@ namespace Minigames.FortFight.Core
|
||||
|
||||
#endregion
|
||||
|
||||
#region ITouchInputConsumer Implementation
|
||||
#region Override Methods
|
||||
|
||||
public void OnTap(Vector2 worldPosition)
|
||||
protected override float GetProjectileMass()
|
||||
{
|
||||
// Slingshot uses hold/drag, not tap
|
||||
return _currentAmmo?.GetMass() ?? base.GetProjectileMass();
|
||||
}
|
||||
|
||||
public void OnHoldStart(Vector2 worldPosition)
|
||||
protected override void StartDrag(Vector2 worldPosition)
|
||||
{
|
||||
if (!IsEnabled) return;
|
||||
StartDrag(worldPosition);
|
||||
}
|
||||
|
||||
public void OnHoldMove(Vector2 worldPosition)
|
||||
{
|
||||
if (!IsEnabled || !_isDragging) return;
|
||||
UpdateDrag(worldPosition);
|
||||
}
|
||||
|
||||
public void OnHoldEnd(Vector2 worldPosition)
|
||||
{
|
||||
if (!IsEnabled || !_isDragging) return;
|
||||
EndDrag(worldPosition);
|
||||
// Check ammo before starting drag
|
||||
if (_currentAmmo == null)
|
||||
{
|
||||
if (showDebugLogs) Logging.Warning("[SlingshotController] No ammo selected!");
|
||||
return;
|
||||
}
|
||||
|
||||
base.StartDrag(worldPosition);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Drag Handling
|
||||
#region Abstract Method Implementations
|
||||
|
||||
private void StartDrag(Vector2 worldPosition)
|
||||
protected override void ShowPreview()
|
||||
{
|
||||
if (_currentAmmo == null)
|
||||
{
|
||||
if (ShowDebugLogs) Logging.Warning("[SlingshotController] No ammo selected!");
|
||||
return;
|
||||
}
|
||||
|
||||
_isDragging = true;
|
||||
// Use the projectile spawn point as the anchor, not the touch position
|
||||
// This makes it work like Angry Birds - pull back from slingshot to launch forward
|
||||
_dragStartPosition = projectileSpawnPoint.position;
|
||||
|
||||
// Show trajectory preview
|
||||
if (trajectoryPreview != null)
|
||||
{
|
||||
trajectoryPreview.Show();
|
||||
}
|
||||
|
||||
if (ShowDebugLogs) Logging.Debug($"[SlingshotController] Started drag at {worldPosition}, anchor at spawn point {_dragStartPosition}");
|
||||
trajectoryPreview?.Show();
|
||||
}
|
||||
|
||||
private void UpdateDrag(Vector2 currentWorldPosition)
|
||||
protected override void HidePreview()
|
||||
{
|
||||
// Calculate drag vector from spawn point to current drag position
|
||||
// Pull back (away from spawn) = launch forward (toward spawn direction)
|
||||
Vector2 dragVector = _dragStartPosition - currentWorldPosition;
|
||||
|
||||
// Calculate force and direction
|
||||
float dragDistance = dragVector.magnitude;
|
||||
float dragRatio = Mathf.Clamp01(dragDistance / maxDragDistance);
|
||||
|
||||
// Apply configurable max force multiplier
|
||||
float maxMultiplier = CachedSettings?.MaxForceMultiplier ?? 1f;
|
||||
float forceMultiplier = dragRatio * maxMultiplier;
|
||||
float force = forceMultiplier * MaxForce;
|
||||
|
||||
Vector2 direction = dragVector.normalized;
|
||||
|
||||
// Update trajectory preview with projectile mass
|
||||
if (trajectoryPreview != null && _currentAmmo != null)
|
||||
trajectoryPreview?.Hide();
|
||||
}
|
||||
|
||||
protected override void UpdateVisuals(Vector2 currentPosition, Vector2 direction,
|
||||
float force, float dragDistance, float mass)
|
||||
{
|
||||
if (trajectoryPreview != null)
|
||||
{
|
||||
Vector2 worldStartPos = projectileSpawnPoint.position;
|
||||
float mass = _currentAmmo.GetMass();
|
||||
|
||||
// Debug: Log trajectory calculation (uncomment for debugging)
|
||||
// if (showDebugLogs && Time.frameCount % 30 == 0) // Log every 30 frames to avoid spam
|
||||
// {
|
||||
// Logging.Debug($"[Slingshot] Preview - Force: {force:F2}, Mass: {mass:F2}, Velocity: {force/mass:F2}, Dir: {direction}");
|
||||
// }
|
||||
|
||||
trajectoryPreview.UpdateTrajectory(worldStartPos, direction, force, mass);
|
||||
trajectoryPreview.UpdateTrajectory(launchAnchor.position, direction, force, mass);
|
||||
}
|
||||
}
|
||||
|
||||
private void EndDrag(Vector2 currentWorldPosition)
|
||||
protected override void PerformLaunch(Vector2 direction, float force)
|
||||
{
|
||||
_isDragging = false;
|
||||
|
||||
// Hide trajectory
|
||||
if (trajectoryPreview != null)
|
||||
{
|
||||
trajectoryPreview.Hide();
|
||||
}
|
||||
|
||||
// Calculate final launch parameters from spawn point to final drag position
|
||||
Vector2 dragVector = _dragStartPosition - currentWorldPosition;
|
||||
float dragDistance = dragVector.magnitude;
|
||||
float dragRatio = Mathf.Clamp01(dragDistance / maxDragDistance);
|
||||
|
||||
// Apply configurable max force multiplier
|
||||
float maxMultiplier = CachedSettings?.MaxForceMultiplier ?? 1f;
|
||||
float forceMultiplier = dragRatio * maxMultiplier;
|
||||
float force = forceMultiplier * MaxForce;
|
||||
|
||||
Vector2 direction = dragVector.normalized;
|
||||
|
||||
// Check against configurable minimum force threshold
|
||||
float minMultiplier = CachedSettings?.MinForceMultiplier ?? 0.1f;
|
||||
float minForce = minMultiplier * MaxForce;
|
||||
|
||||
// Launch projectile if force exceeds minimum
|
||||
if (force >= minForce)
|
||||
{
|
||||
if (ShowDebugLogs && _currentAmmo != null)
|
||||
{
|
||||
float mass = _currentAmmo.GetMass();
|
||||
float velocity = force / mass;
|
||||
Logging.Debug($"[Slingshot] Launch - Force: {force:F2}, Mass: {mass:F2}, Velocity: {velocity:F2}, Dir: {direction}");
|
||||
}
|
||||
|
||||
LaunchProjectile(direction, force);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ShowDebugLogs) Logging.Debug($"[SlingshotController] Drag too short - force {force:F2} < min {minForce:F2}");
|
||||
}
|
||||
LaunchProjectile(direction, force);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -252,7 +167,7 @@ namespace Minigames.FortFight.Core
|
||||
public void SetAmmo(ProjectileConfig ammoConfig)
|
||||
{
|
||||
_currentAmmo = ammoConfig;
|
||||
if (ShowDebugLogs) Logging.Debug($"[SlingshotController] Ammo set to: {ammoConfig?.displayName ?? "null"}");
|
||||
if (showDebugLogs) Logging.Debug($"[SlingshotController] Ammo set to: {ammoConfig?.displayName ?? "null"}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -266,8 +181,8 @@ namespace Minigames.FortFight.Core
|
||||
return;
|
||||
}
|
||||
|
||||
// Spawn projectile
|
||||
GameObject projectileObj = Instantiate(_currentAmmo.prefab, projectileSpawnPoint.position, Quaternion.identity);
|
||||
// Spawn projectile at launch anchor
|
||||
GameObject projectileObj = Instantiate(_currentAmmo.prefab, launchAnchor.position, Quaternion.identity);
|
||||
_activeProjectile = projectileObj.GetComponent<ProjectileBase>();
|
||||
|
||||
if (_activeProjectile == null)
|
||||
@@ -290,7 +205,7 @@ namespace Minigames.FortFight.Core
|
||||
trajectoryPreview.LockTrajectory(lockDuration);
|
||||
}
|
||||
|
||||
if (ShowDebugLogs) Logging.Debug($"[SlingshotController] Launched {_currentAmmo?.displayName ?? "projectile"} with force {force}");
|
||||
if (showDebugLogs) Logging.Debug($"[SlingshotController] Launched {_currentAmmo?.displayName ?? "projectile"} with force {force}");
|
||||
|
||||
// Fire event
|
||||
OnProjectileLaunched?.Invoke(_activeProjectile);
|
||||
@@ -324,7 +239,7 @@ namespace Minigames.FortFight.Core
|
||||
float speed = velocity.magnitude;
|
||||
float force = mass * speed;
|
||||
|
||||
if (ShowDebugLogs)
|
||||
if (showDebugLogs)
|
||||
{
|
||||
Logging.Debug($"[Slingshot] LaunchWithVelocity - Velocity: {velocity}, Mass: {mass:F2}, Force: {force:F2}");
|
||||
}
|
||||
@@ -341,34 +256,7 @@ namespace Minigames.FortFight.Core
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Enable/Disable
|
||||
|
||||
/// <summary>
|
||||
/// Enable slingshot (allow aiming/launching)
|
||||
/// </summary>
|
||||
public void Enable()
|
||||
{
|
||||
IsEnabled = true;
|
||||
if (ShowDebugLogs) Logging.Debug("[SlingshotController] Enabled");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disable slingshot (prevent aiming/launching)
|
||||
/// </summary>
|
||||
public void Disable()
|
||||
{
|
||||
IsEnabled = false;
|
||||
_isDragging = false;
|
||||
|
||||
if (trajectoryPreview != null)
|
||||
{
|
||||
trajectoryPreview.Hide();
|
||||
}
|
||||
|
||||
if (ShowDebugLogs) Logging.Debug("[SlingshotController] Disabled");
|
||||
}
|
||||
|
||||
#endregion
|
||||
// Note: Enable/Disable methods now handled by base DragLaunchController class
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user