1
1
using System . Collections . Generic ;
2
2
using System . Linq ;
3
3
using System . Text . RegularExpressions ;
4
+ using Ludiq . OdinSerializer . Utilities ;
4
5
using UnityEditor ;
5
6
using UnityEngine ;
6
7
using UnityEngine . UIElements ;
@@ -21,6 +22,7 @@ private static void ShowWindow()
21
22
public SerializedObject serializedObject ;
22
23
public float maxDistance = 1.0f ;
23
24
public LayerMask layerMask = 0x801 ;
25
+ public bool useBounds ;
24
26
public QueryTriggerInteraction queryTriggerInteraction = QueryTriggerInteraction . Ignore ;
25
27
26
28
@@ -55,6 +57,17 @@ private static Vector2 ParseLatLon(string text)
55
57
return new Vector2 ( float . Parse ( split [ 0 ] ) , float . Parse ( split [ 1 ] ) ) ;
56
58
}
57
59
60
+ private static float GetGroundDistance ( Vector3 origin , float maxDistance , LayerMask layerMask , QueryTriggerInteraction queryTriggerInteraction )
61
+ {
62
+ var hitUp = Physics . Raycast ( origin + Vector3 . up * maxDistance , Vector3 . down , out var up , maxDistance , layerMask , queryTriggerInteraction ) ;
63
+ if ( hitUp ) return maxDistance - up . distance ;
64
+
65
+ var hitDown = Physics . Raycast ( origin , Vector3 . down , out var down , maxDistance , layerMask , queryTriggerInteraction ) ;
66
+ if ( hitDown ) return - down . distance ;
67
+
68
+ return 0 ;
69
+ }
70
+
58
71
private void OnGUI ( )
59
72
{
60
73
serializedObject . Update ( ) ;
@@ -97,18 +110,51 @@ private void OnGUI()
97
110
case nameof ( queryTriggerInteraction ) :
98
111
if ( GUILayout . Button ( "Snap To Ground" ) )
99
112
{
100
- var transforms = Selection . transforms ;
101
- foreach ( var transform in transforms )
113
+ try
102
114
{
103
- Undo . RecordObject ( transform , "Snap To Ground" ) ;
104
- var hitUp = Physics . Raycast ( transform . position + Vector3 . up * maxDistance , Vector3 . down , out var up , maxDistance , layerMask , queryTriggerInteraction ) ;
105
- if ( hitUp ) transform . position = up . point ;
106
- else
115
+ var transforms = Selection . transforms ;
116
+ var i = 0 ;
117
+ foreach ( var transform in transforms )
107
118
{
108
- var hitDown = Physics . Raycast ( transform . position , Vector3 . down , out var down , maxDistance , layerMask , queryTriggerInteraction ) ;
109
- if ( hitDown ) transform . position = down . point ;
119
+ EditorUtility . DisplayProgressBar ( "Snap To Ground" , transform . gameObject . name , ( float ) i ++ / transforms . Length ) ;
120
+ Undo . RecordObject ( transform , "Snap To Ground" ) ;
121
+
122
+ var renderer = transform . GetComponent < Renderer > ( ) ;
123
+ if ( useBounds && renderer )
124
+ {
125
+ var bounds = renderer . bounds ;
126
+ var center = bounds . center ;
127
+ var extents = bounds . extents ;
128
+
129
+ var y = center . y - extents . y ;
130
+
131
+ var left = center . x - extents . x ;
132
+ var right = center . x + extents . x ;
133
+
134
+ var top = center . z + extents . z ;
135
+ var bottom = center . z - extents . z ;
136
+
137
+ var points = new [ ] {
138
+ transform . position ,
139
+ center + Vector3 . Scale ( extents , new Vector3 ( 1 , - 1 , 1 ) ) ,
140
+ center + Vector3 . Scale ( extents , new Vector3 ( - 1 , - 1 , 1 ) ) ,
141
+ center + Vector3 . Scale ( extents , new Vector3 ( 1 , - 1 , - 1 ) ) ,
142
+ center + Vector3 . Scale ( extents , new Vector3 ( - 1 , - 1 , - 1 ) ) ,
143
+ } ;
144
+
145
+ var distance = points . Select ( origin => GetGroundDistance ( origin , maxDistance , layerMask , queryTriggerInteraction ) ) . Min ( ) ;
146
+ transform . position += Vector3 . up * distance ;
147
+ }
148
+ else
149
+ {
150
+ transform . position += Vector3 . up * GetGroundDistance ( transform . position , maxDistance , layerMask , queryTriggerInteraction ) ;
151
+ }
110
152
}
111
153
}
154
+ finally
155
+ {
156
+ EditorUtility . ClearProgressBar ( ) ;
157
+ }
112
158
}
113
159
EditorGUILayout . Separator ( ) ;
114
160
break ;
0 commit comments