using UnityEngine; namespace AibisDream.MiniGame.Language { public static class ExpressionParticleGeometry { public static bool TryGetConnection( TextParticle first, TextParticle second, float centerDistanceLimit, float edgeDistanceLimit, out Vector3 from, out Vector3 to, out float proximity) { from = first != null ? first.transform.position : Vector3.zero; to = second != null ? second.transform.position : Vector3.zero; proximity = 0f; if (first == null || second == null) return false; float centerDistance = Vector3.Distance( first.transform.position, second.transform.position); bool centerConnected = centerDistanceLimit > 0f && centerDistance < centerDistanceLimit; Bounds firstBounds = first.GetVisualWorldBounds(); Bounds secondBounds = second.GetVisualWorldBounds(); float edgeDistance = BoundsDistance(firstBounds, secondBounds); bool edgeConnected = edgeDistanceLimit > 0f && edgeDistance <= edgeDistanceLimit; if (!centerConnected && !edgeConnected) return false; from = firstBounds.ClosestPoint(secondBounds.center); to = secondBounds.ClosestPoint(firstBounds.center); if ((to - from).sqrMagnitude < 0.000001f) { from = first.transform.position; to = second.transform.position; } float centerProximity = centerConnected ? 1f - Mathf.Clamp01(centerDistance / centerDistanceLimit) : 0f; float edgeProximity = edgeConnected ? 1f - Mathf.Clamp01(edgeDistance / Mathf.Max(0.0001f, edgeDistanceLimit)) : 0f; proximity = Mathf.Max(centerProximity, edgeProximity); return true; } public static float BoundsDistance(Bounds first, Bounds second) { float dx = Mathf.Max( first.min.x - second.max.x, second.min.x - first.max.x, 0f); float dy = Mathf.Max( first.min.y - second.max.y, second.min.y - first.max.y, 0f); return Mathf.Sqrt(dx * dx + dy * dy); } public static bool TryGetSeparation( Bounds first, Bounds second, float padding, out Vector2 direction, out float overlap) { float overlapX = Mathf.Min(first.max.x, second.max.x) - Mathf.Max(first.min.x, second.min.x) + padding; float overlapY = Mathf.Min(first.max.y, second.max.y) - Mathf.Max(first.min.y, second.min.y) + padding; if (overlapX <= 0f || overlapY <= 0f) { direction = Vector2.zero; overlap = 0f; return false; } Vector2 centerDelta = first.center - second.center; if (overlapX <= overlapY) { direction = new Vector2(centerDelta.x >= 0f ? 1f : -1f, 0f); overlap = overlapX; } else { direction = new Vector2(0f, centerDelta.y >= 0f ? 1f : -1f); overlap = overlapY; } return true; } } }