1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Linq ;
4
+ using UnityEngine ;
5
+
6
+ namespace _Framework . Scripts . Extensions
7
+ {
8
+ public static class BoundsExtensions
9
+ {
10
+ public static Vector3 [ ] GetVertices ( this Bounds bounds ) => new [ ]
11
+ {
12
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( - bounds . extents . x , - bounds . extents . y , - bounds . extents . z ) ,
13
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( bounds . extents . x , - bounds . extents . y , - bounds . extents . z ) ,
14
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( - bounds . extents . x , - bounds . extents . y , bounds . extents . z ) ,
15
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( bounds . extents . x , - bounds . extents . y , bounds . extents . z ) ,
16
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( - bounds . extents . x , bounds . extents . y , - bounds . extents . z ) ,
17
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( bounds . extents . x , bounds . extents . y , - bounds . extents . z ) ,
18
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( - bounds . extents . x , bounds . extents . y , bounds . extents . z ) ,
19
+ new Vector3 ( bounds . center . x , bounds . center . y , bounds . center . z ) + new Vector3 ( bounds . extents . x , bounds . extents . y , bounds . extents . z ) ,
20
+ } ;
21
+
22
+ public static Bounds ToBounds ( this IEnumerable < Vector3 > vertices )
23
+ {
24
+ return vertices . ToArray ( ) . ToBounds ( ) ;
25
+ }
26
+
27
+ public static Bounds ToBounds ( this Vector3 [ ] vertices )
28
+ {
29
+ var min = Vector3 . one * float . MaxValue ;
30
+ var max = Vector3 . one * float . MinValue ;
31
+
32
+ for ( int i = 0 ; i < vertices . Length ; i ++ )
33
+ {
34
+ min = vertices [ i ] . Min ( min ) ;
35
+ max = vertices [ i ] . Max ( max ) ;
36
+ }
37
+
38
+ return new Bounds ( ( max - min ) / 2 + min , max - min ) ;
39
+ }
40
+
41
+ public static Bounds Encapsulate ( this List < Bounds > bounds )
42
+ {
43
+ if ( bounds . Count == 0 )
44
+ throw new ArgumentException ( "Bounds list is empty." ) ;
45
+
46
+ if ( bounds . Count == 1 )
47
+ return bounds [ 0 ] ;
48
+
49
+ return bounds
50
+ . Aggregate ( ( a , b ) =>
51
+ {
52
+ a . Encapsulate ( b ) ;
53
+ return a ;
54
+ } ) ;
55
+ }
56
+ public static Bounds TransformBounds ( this Transform from , Transform to , Bounds bounds )
57
+ {
58
+ return bounds . GetVertices ( )
59
+ . Select ( bv => from . transform . TransformPoint ( bv , to . transform ) )
60
+ . ToBounds ( ) ;
61
+ }
62
+
63
+ public static Bounds GetCompositeMeshBounds ( this GameObject go )
64
+ {
65
+ var boundsInObject = go . GetComponentsInChildren < MeshFilter > ( true )
66
+ . Select ( r => ( r . mesh ?? r . sharedMesh ) . bounds )
67
+ . Where ( bounds => bounds . min != bounds . max )
68
+ . ToArray ( ) ;
69
+
70
+ if ( boundsInObject . Length == 0 )
71
+ return new Bounds ( ) ;
72
+
73
+ return boundsInObject
74
+ . Aggregate ( ( a , b ) =>
75
+ {
76
+ a . Encapsulate ( b ) ;
77
+ return a ;
78
+ } ) ;
79
+ }
80
+
81
+ public static Bounds GetCompositeRendererBounds ( this GameObject go )
82
+ {
83
+ var boundsInObject = go . GetComponentsInChildren < Renderer > ( true )
84
+ . Select ( r => r . bounds )
85
+ . Where ( bounds => bounds . min != bounds . max )
86
+ . ToArray ( ) ;
87
+
88
+ if ( boundsInObject . Length == 0 )
89
+ return new Bounds ( ) ;
90
+
91
+ return boundsInObject
92
+ . Aggregate ( ( a , b ) =>
93
+ {
94
+ a . Encapsulate ( b ) ;
95
+ return a ;
96
+ } ) ;
97
+ }
98
+
99
+ public static Bounds GetCompositeBoundingBounds ( this GameObject go , LayerMask ? ignore = null )
100
+ {
101
+ var boundsInObject = go . GetComponentsInChildren < Renderer > ( true )
102
+ . Where ( r => ignore == null || ignore . Value . Contains ( r . gameObject . layer ) == false )
103
+ . Where ( r => r is ParticleSystemRenderer == false )
104
+ . Select ( r => r . bounds )
105
+ . Where ( bounds => bounds . min != bounds . max )
106
+ . ToArray ( ) ;
107
+
108
+ if ( boundsInObject . Length == 0 )
109
+ return new Bounds ( ) ;
110
+
111
+ return boundsInObject
112
+ . Aggregate ( ( a , b ) =>
113
+ {
114
+ a . Encapsulate ( b ) ;
115
+ return a ;
116
+ } ) ;
117
+ }
118
+
119
+ public static bool Contains ( this LayerMask mask , int layer )
120
+ {
121
+ return mask == ( mask | ( 1 << layer ) ) ;
122
+ }
123
+
124
+ public static Bounds GetCompositeColliderBounds ( this GameObject go )
125
+ {
126
+ var boundsInObject = go . GetComponentsInChildren < Collider > ( true )
127
+ . Select ( r => r . bounds )
128
+ . Where ( bounds => bounds . min != bounds . max )
129
+ . ToArray ( ) ;
130
+
131
+ if ( boundsInObject . Length == 0 )
132
+ return new Bounds ( ) ;
133
+
134
+ if ( boundsInObject . Length == 1 )
135
+ return boundsInObject [ 0 ] ;
136
+
137
+ return boundsInObject
138
+ . Aggregate ( ( a , b ) =>
139
+ {
140
+ a . Encapsulate ( b ) ;
141
+ return a ;
142
+ } ) ;
143
+ }
144
+
145
+ public static Bounds GetCompositeColliderBounds ( this GameObject [ ] go )
146
+ {
147
+ var boundsInObject = go
148
+ . Select ( r => r . GetCompositeColliderBounds ( ) )
149
+ . Where ( bounds => bounds . min != bounds . max )
150
+ . ToArray ( ) ;
151
+
152
+ if ( boundsInObject . Length == 0 )
153
+ return new Bounds ( ) ;
154
+
155
+ if ( boundsInObject . Length == 1 )
156
+ return boundsInObject [ 0 ] ;
157
+
158
+ return boundsInObject
159
+ . Aggregate ( ( a , b ) =>
160
+ {
161
+ a . Encapsulate ( b ) ;
162
+ return a ;
163
+ } ) ;
164
+ }
165
+
166
+ public static Bounds ? GetLocalCompositeMeshBounds ( this GameObject go )
167
+ {
168
+ var boundsInObject = go . GetComponentsInChildren < MeshFilter > ( true )
169
+ . Select ( mf =>
170
+ {
171
+ var bounds = ( mf . mesh ?? mf . sharedMesh ) . bounds ;
172
+ var localBound = mf . transform . TransformBounds ( go . transform , bounds ) ;
173
+ return localBound ;
174
+ } )
175
+ . Where ( bounds => bounds . min != bounds . max )
176
+ . ToArray ( ) ;
177
+
178
+ if ( boundsInObject . Length == 0 )
179
+ return null ;
180
+
181
+ if ( boundsInObject . Length == 1 )
182
+ return boundsInObject . First ( ) ;
183
+
184
+ return boundsInObject
185
+ . Aggregate ( ( a , b ) =>
186
+ {
187
+ a . Encapsulate ( b ) ;
188
+ return a ;
189
+ } ) ;
190
+ }
191
+ }
192
+ }
0 commit comments