- A Settings Provider system to utilize addressables for loading settings at runtime - An editor UI for easy modifications of the settings objects - A split out developer settings functionality to keep gameplay and nitty-gritty details separately - Most settings migrated out of game objects and into the new system - An additional Editor utility for fetching the settings at editor runtime, for gizmos, visualization etc Co-authored-by: Michal Pikulski <michal.a.pikulski@gmail.com> Co-authored-by: AlexanderT <alexander@foolhardyhorizons.com> Reviewed-on: #7
151 lines
5.8 KiB
C#
151 lines
5.8 KiB
C#
using UnityEngine;
|
|
using System.Collections;
|
|
using AppleHills.Core.Settings;
|
|
|
|
namespace Minigames.DivingForPictures
|
|
{
|
|
/// <summary>
|
|
/// Collision behavior that bumps the player toward the center of the trench.
|
|
/// Uses trigger-based collision detection with coroutine-based bump timing.
|
|
/// </summary>
|
|
public class TileBumpCollision : PlayerCollisionBehavior
|
|
{
|
|
private bool _isBumping;
|
|
private Coroutine _bumpCoroutine;
|
|
|
|
protected override void HandleCollisionResponse(Collider2D obstacle)
|
|
{
|
|
// Check if the obstacle is on the TrenchTileLayer
|
|
if (obstacle.gameObject.layer != _devSettings.TrenchTileLayer)
|
|
{
|
|
// If not on the trench tile layer, don't process the collision
|
|
Debug.Log($"[TileBumpCollision] Ignored collision with object on layer {obstacle.gameObject.layer} (expected {_devSettings.TrenchTileLayer})");
|
|
return;
|
|
}
|
|
|
|
// Use bump mode from developer settings
|
|
switch (_devSettings.BumpMode)
|
|
{
|
|
case BumpMode.Impulse:
|
|
StartImpulseBump();
|
|
break;
|
|
|
|
case BumpMode.SmoothToCenter:
|
|
StartSmoothMoveToCenter();
|
|
break;
|
|
}
|
|
|
|
Debug.Log($"[TileBumpCollision] Collision handled with {_devSettings.BumpMode} mode");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts an impulse bump toward the center with force-based distance
|
|
/// </summary>
|
|
private void StartImpulseBump()
|
|
{
|
|
if (playerCharacter == null) return;
|
|
|
|
float currentX = playerCharacter.transform.position.x;
|
|
|
|
// Calculate bump distance based on force and current position
|
|
float directionToCenter = currentX > 0 ? -1f : 1f; // Direction toward center
|
|
|
|
// Calculate target position - closer to center based on bump force
|
|
float bumpDistance = _gameSettings.BumpForce * 0.2f; // Scale factor for distance
|
|
float targetX = currentX + (directionToCenter * bumpDistance);
|
|
|
|
// Clamp to center if we would overshoot
|
|
if ((currentX > 0 && targetX < 0) || (currentX < 0 && targetX > 0))
|
|
{
|
|
targetX = 0f;
|
|
}
|
|
|
|
float bumpDuration = 0.5f; // Fixed duration for impulse
|
|
|
|
StartBump(currentX, targetX, bumpDuration);
|
|
|
|
Debug.Log($"[TileBumpCollision] Starting impulse bump from X={currentX} to X={targetX} (force={_gameSettings.BumpForce})");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts smooth movement to the center
|
|
/// </summary>
|
|
private void StartSmoothMoveToCenter()
|
|
{
|
|
if (playerCharacter == null) return;
|
|
|
|
float currentX = playerCharacter.transform.position.x;
|
|
float distanceToCenter = Mathf.Abs(currentX);
|
|
|
|
float targetX = 0f; // Always move to center
|
|
float bumpDuration = distanceToCenter / _gameSettings.SmoothMoveSpeed; // Duration based on distance and speed
|
|
|
|
StartBump(currentX, targetX, bumpDuration);
|
|
|
|
Debug.Log($"[TileBumpCollision] Starting smooth move to center from X={currentX} (speed={_gameSettings.SmoothMoveSpeed}, duration={bumpDuration:F2}s)");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Common bump initialization using coroutines
|
|
/// </summary>
|
|
private void StartBump(float startX, float targetX, float duration)
|
|
{
|
|
// Stop any existing bump
|
|
if (_bumpCoroutine != null)
|
|
{
|
|
StopCoroutine(_bumpCoroutine);
|
|
_bumpCoroutine = null;
|
|
}
|
|
|
|
_isBumping = true;
|
|
|
|
// Start bump coroutine
|
|
_bumpCoroutine = StartCoroutine(BumpCoroutine(startX, targetX, duration));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Coroutine that handles the bump movement over time
|
|
/// </summary>
|
|
private IEnumerator BumpCoroutine(float startX, float targetX, float duration)
|
|
{
|
|
float elapsedTime = 0f;
|
|
|
|
while (elapsedTime < duration)
|
|
{
|
|
elapsedTime += Time.deltaTime;
|
|
|
|
// Calculate progress and apply curve
|
|
float progress = elapsedTime / duration;
|
|
float curveValue = _devSettings.BumpCurve.Evaluate(progress);
|
|
|
|
// Interpolate position
|
|
float currentX = Mathf.Lerp(startX, targetX, curveValue);
|
|
|
|
// Apply the position to the player character
|
|
if (playerCharacter != null)
|
|
{
|
|
Vector3 currentPos = playerCharacter.transform.position;
|
|
currentPos.x = Mathf.Clamp(currentX, _gameSettings.ClampXMin, _gameSettings.ClampXMax);
|
|
playerCharacter.transform.position = currentPos;
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
// Ensure we end exactly at target
|
|
if (playerCharacter != null)
|
|
{
|
|
Vector3 currentPos = playerCharacter.transform.position;
|
|
float clampedTargetX = Mathf.Clamp(targetX, _gameSettings.ClampXMin, _gameSettings.ClampXMax);
|
|
playerCharacter.transform.position = new Vector3(clampedTargetX, currentPos.y, currentPos.z);
|
|
}
|
|
|
|
// Bump finished
|
|
_isBumping = false;
|
|
_bumpCoroutine = null;
|
|
|
|
Debug.Log("[TileBumpCollision] Bump movement completed");
|
|
}
|
|
}
|
|
}
|