using UnityEngine; namespace BumpCombat.Enemies { /// /// The authored timing contract for the first Lancer thrust pilot. /// The tip is the only moving collision sample; the shaft is visual only. /// public static class LancerAttackMotion { public const float WarningStartReachFraction = 0.65f; public const float WarningEndReachFraction = 0.35f; public const float ActiveExtensionEndFraction = 0.65f; public const float HandAnchorPixelsX = 10f; public const float HandAnchorPixelsY = 6f; public const float PixelsPerUnit = 32f; public static float EvaluateWarningReachFraction(float normalizedWarning) { return Mathf.Lerp( WarningStartReachFraction, WarningEndReachFraction, Mathf.Clamp01(normalizedWarning)); } public static float EvaluateActiveReachFraction(float normalizedActive) { float progress = Mathf.Clamp01(normalizedActive); if (progress <= ActiveExtensionEndFraction) { return Mathf.Lerp( WarningEndReachFraction, 1f, progress / ActiveExtensionEndFraction); } return Mathf.Lerp( 1f, WarningEndReachFraction, (progress - ActiveExtensionEndFraction) / (1f - ActiveExtensionEndFraction)); } public static Vector2 GetHandAnchorOffset( Vector2 lockedDirection, float worldScale = 1f) { float side = lockedDirection.x < 0f ? -1f : 1f; return new Vector2( side * HandAnchorPixelsX / PixelsPerUnit, HandAnchorPixelsY / PixelsPerUnit) * worldScale; } public static Vector2 GetTipPosition( Vector2 rootPosition, Vector2 lockedDirection, float attackLength, float normalizedReach, float worldScale = 1f) { Vector2 direction = lockedDirection.sqrMagnitude > 0.0001f ? lockedDirection.normalized : Vector2.right; Vector2 hand = rootPosition + GetHandAnchorOffset( direction, worldScale); float rootReach = Mathf.Max(0f, attackLength) * Mathf.Clamp01(normalizedReach); float handLength = Mathf.Max( 0f, rootReach - Vector2.Dot(hand - rootPosition, direction)); return hand + direction * handLength; } public static bool IsDamageWindow(float normalizedActive) { return Mathf.Clamp01(normalizedActive) <= ActiveExtensionEndFraction + 0.0001f; } } }