namespace Zinnia.Tracking.Collision.Active.Operation
{
using System;
using System.Collections.Generic;
using UnityEngine;
using Zinnia.Extension;
///
/// Sorts the given collision collection based on which collision components are nearest to the specified .
///
public class NearestSorter : MonoBehaviour
{
///
/// Compares two based on their containing 's distance to a given .
///
protected class EventDataComparer : IComparer
{
[Tooltip("The position to check against.")]
[SerializeField]
private Vector3 sourcePosition;
///
/// The position to check against.
///
public Vector3 SourcePosition
{
get
{
return sourcePosition;
}
set
{
sourcePosition = value;
}
}
///
public virtual int Compare(CollisionNotifier.EventData x, CollisionNotifier.EventData y)
{
Transform xTransform = x.ColliderData.GetContainingTransform();
Transform yTransform = y.ColliderData.GetContainingTransform();
if (xTransform == null && yTransform == null)
{
return 0;
}
float distance1 = xTransform != null ? Vector3.Distance(xTransform.position, SourcePosition) : float.MaxValue;
float distance2 = yTransform != null ? Vector3.Distance(yTransform.position, SourcePosition) : float.MaxValue;
return distance1.CompareTo(distance2);
}
}
[Tooltip("The source to determine the closest collision to.")]
[SerializeField]
private GameObject source;
///
/// The source to determine the closest collision to.
///
public GameObject Source
{
get
{
return source;
}
set
{
source = value;
}
}
///
/// The sorted list.
///
public ActiveCollisionsContainer.EventData SortedList
{
get;
protected set;
} = new ActiveCollisionsContainer.EventData();
///
/// Emitted when the collection is sorted.
///
public ActiveCollisionsContainer.ActiveCollisionUnityEvent Sorted = new ActiveCollisionsContainer.ActiveCollisionUnityEvent();
///
/// Compares two .
///
protected static readonly EventDataComparer Comparer = new EventDataComparer();
///
/// The comparison does.
///
protected static readonly Comparison Comparison = Comparer.Compare;
///
/// Clears .
///
public virtual void ClearSource()
{
if (!this.IsValidState())
{
return;
}
Source = default;
}
///
/// Sorts the given collision collection by the collisions that are nearest to the source .
///
/// The original collision collection.
public virtual void DoSort(ActiveCollisionsContainer.EventData originalList)
{
Sort(originalList);
}
///
/// Sorts the given collision collection by the collisions that are nearest to the source .
///
/// The original collision collection.
/// The sorted collision collection.
public virtual ActiveCollisionsContainer.EventData Sort(ActiveCollisionsContainer.EventData originalList)
{
if (!this.CheckIsActiveAndEnabled() || Source == null)
{
return originalList;
}
SortedList.Set(originalList);
Comparer.SourcePosition = Source.transform.position;
SortedList.ActiveCollisions.Sort(Comparison);
Sorted?.Invoke(SortedList);
return SortedList;
}
}
}