using System.Collections.Generic; using UnityEngine; namespace Flexalon { /// A drag target allows a layout to accept dragged FlexalonInteractable objects. [AddComponentMenu("Flexalon/Flexalon Drag Target"), HelpURL("https://www.flexalon.com/docs/dragging"), DisallowMultipleComponent] public class FlexalonDragTarget : MonoBehaviour { [SerializeField] private bool _canRemoveObjects = true; /// Whether objects can be removed from the layout by dragging them from this target. public bool CanRemoveObjects { get => _canRemoveObjects; set => _canRemoveObjects = value; } [SerializeField] private bool _canAddObjects = true; /// Whether objects can be added to the layout by dragging them to this target. public bool CanAddObjects { get => _canAddObjects; set => _canAddObjects = value; } [SerializeField] private int _minObjects; /// The minimum number of objects that must remain in this layout. public int MinObjects { get => _minObjects; set => _minObjects = value; } [SerializeField] private int _maxObjects; /// The maximum number of objects that can be added to the layout. public int MaxObjects { get => _maxObjects; set => _maxObjects = value; } [SerializeField] private Vector3 _margin; /// Extra margin around the layout size to use for hit testing. public Vector3 Margin { get => _margin; set => _margin = value; } private FlexalonNode _node; private static HashSet _dragTargets = new HashSet(); public static IReadOnlyCollection DragTargets => _dragTargets; void OnEnable() { _node = Flexalon.GetOrCreateNode(gameObject); _dragTargets.Add(this); } void OnDisable() { _node = null; _dragTargets.Remove(this); } internal bool OverlapsSphere(Vector3 position, float radius) { var center = _node.Result.AdapterBounds.center; var extents = (_node.Result.AdapterBounds.size + _margin * 2) / 2; var min = center - extents; var max = center + extents; // Transform the sphere center into the OBB's local coordinate system Vector3 localSphereCenter = transform.InverseTransformPoint(position); // Calculate the closest point on the OBB to the sphere center Vector3 closestPointOnOBB = Vector3.Min(Vector3.Max(localSphereCenter, min), max); // Calculate the distance between the closest point and the sphere center float distanceSquared = (closestPointOnOBB - localSphereCenter).sqrMagnitude; // Check if the distance is less than or equal to the sphere's radius squared return distanceSquared <= radius * radius; } } }