miepzerino
2025-03-29 ad79d9ca49274cc660fc2030a071b24314f0f210
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
using System.Collections.Generic;
using UnityEngine;
 
namespace Flexalon
{
    /// <summary> A drag target allows a layout to accept  dragged FlexalonInteractable objects. </summary>
    [AddComponentMenu("Flexalon/Flexalon Drag Target"), HelpURL("https://www.flexalon.com/docs/dragging"), DisallowMultipleComponent]
    public class FlexalonDragTarget : MonoBehaviour
    {
        [SerializeField]
        private bool _canRemoveObjects = true;
        /// <summary> Whether objects can be removed from the layout by dragging them from this target. </summary>
        public bool CanRemoveObjects {
            get => _canRemoveObjects;
            set => _canRemoveObjects = value;
        }
 
        [SerializeField]
        private bool _canAddObjects = true;
        /// <summary> Whether objects can be added to the layout by dragging them to this target. </summary>
        public bool CanAddObjects {
            get => _canAddObjects;
            set => _canAddObjects = value;
        }
 
        [SerializeField]
        private int _minObjects;
        /// <summary> The minimum number of objects that must remain in this layout. </summary>
        public int MinObjects {
            get => _minObjects;
            set => _minObjects = value;
        }
 
        [SerializeField]
        private int _maxObjects;
        /// <summary> The maximum number of objects that can be added to the layout. </summary>
        public int MaxObjects {
            get => _maxObjects;
            set => _maxObjects = value;
        }
 
        [SerializeField]
        private Vector3 _margin;
        /// <summary> Extra margin around the layout size to use for hit testing. </summary>
        public Vector3 Margin {
            get => _margin;
            set => _margin = value;
        }
 
        private FlexalonNode _node;
 
        private static HashSet<FlexalonDragTarget> _dragTargets = new HashSet<FlexalonDragTarget>();
        public static IReadOnlyCollection<FlexalonDragTarget> 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;
        }
    }
}