Files
aibis-dream/Assets/Scripts/MiniGame/HuoShan/Language/ExpressionParticleGeometry.cs
T

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;
}
}
}