107 lines
3.5 KiB
C#
107 lines
3.5 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|