9 using System.Collections;
10 using System.Collections.Generic;
14 namespace Valve.VR.InteractionSystem
17 public static class Util
19 public const float FeetToMeters = 0.3048f;
20 public const float FeetToCentimeters = 30.48f;
21 public const float InchesToMeters = 0.0254f;
22 public const float InchesToCentimeters = 2.54f;
23 public const float MetersToFeet = 3.28084f;
24 public const float MetersToInches = 39.3701f;
25 public const float CentimetersToFeet = 0.0328084f;
26 public const float CentimetersToInches = 0.393701f;
27 public const float KilometersToMiles = 0.621371f;
28 public const float MilesToKilometers = 1.60934f;
33 public static float RemapNumber(
float num,
float low1,
float high1,
float low2,
float high2 )
35 return low2 + ( num - low1 ) * ( high2 - low2 ) / ( high1 - low1 );
40 public static float RemapNumberClamped(
float num,
float low1,
float high1,
float low2,
float high2 )
42 return Mathf.Clamp( RemapNumber( num, low1, high1, low2, high2 ), Mathf.Min( low2, high2 ), Mathf.Max( low2, high2 ) );
47 public static float Approach(
float target,
float value,
float speed )
49 float delta = target - value;
53 else if ( delta < -speed )
63 public static Vector3 BezierInterpolate3( Vector3 p0, Vector3 c0, Vector3 p1,
float t )
65 Vector3 p0c0 = Vector3.Lerp( p0, c0, t );
66 Vector3 c0p1 = Vector3.Lerp( c0, p1, t );
68 return Vector3.Lerp( p0c0, c0p1, t );
73 public static Vector3 BezierInterpolate4( Vector3 p0, Vector3 c0, Vector3 c1, Vector3 p1,
float t )
75 Vector3 p0c0 = Vector3.Lerp( p0, c0, t );
76 Vector3 c0c1 = Vector3.Lerp( c0, c1, t );
77 Vector3 c1p1 = Vector3.Lerp( c1, p1, t );
79 Vector3 x = Vector3.Lerp( p0c0, c0c1, t );
80 Vector3 y = Vector3.Lerp( c0c1, c1p1, t );
93 return Vector3.Lerp( x, y, t );
98 public static Vector3 Vector3FromString(
string szString )
100 string[] szParseString = szString.Substring( 1, szString.Length - 1 ).Split(
',' );
102 float x = float.Parse( szParseString[0] );
103 float y = float.Parse( szParseString[1] );
104 float z = float.Parse( szParseString[2] );
106 Vector3 vReturn =
new Vector3( x, y, z );
113 public static Vector2 Vector2FromString(
string szString )
115 string[] szParseString = szString.Substring( 1, szString.Length - 1 ).Split(
',' );
117 float x = float.Parse( szParseString[0] );
118 float y = float.Parse( szParseString[1] );
120 Vector3 vReturn =
new Vector2( x, y );
127 public static float Normalize(
float value,
float min,
float max )
129 float normalizedValue = ( value - min ) / ( max - min );
131 return normalizedValue;
136 public static Vector3 Vector2AsVector3( Vector2 v )
138 return new Vector3( v.x, 0.0f, v.y );
143 public static Vector2 Vector3AsVector2( Vector3 v )
145 return new Vector2( v.x, v.z );
150 public static float AngleOf( Vector2 v )
152 float fDist = v.magnitude;
156 return Mathf.Acos( v.x / fDist );
160 return Mathf.Acos( -v.x / fDist ) + Mathf.PI;
166 public static float YawOf( Vector3 v )
168 float fDist = v.magnitude;
172 return Mathf.Acos( v.x / fDist );
176 return Mathf.Acos( -v.x / fDist ) + Mathf.PI;
182 public static void Swap<T>( ref T lhs, ref T rhs )
191 public static void Shuffle<T>( T[] array )
193 for (
int i = array.Length - 1; i > 0; i-- )
195 int r = UnityEngine.Random.Range( 0, i );
196 Swap( ref array[i], ref array[r] );
202 public static void Shuffle<T>( List<T> list )
204 for (
int i = list.Count - 1; i > 0; i-- )
206 int r = UnityEngine.Random.Range( 0, i );
215 public static int RandomWithLookback(
int min,
int max, List<int> history,
int historyCount )
217 int index = UnityEngine.Random.Range( min, max - history.Count );
219 for (
int i = 0; i < history.Count; i++ )
221 if ( index >= history[i] )
227 history.Add( index );
229 if ( history.Count > historyCount )
231 history.RemoveRange( 0, history.Count - historyCount );
239 public static Transform FindChild( Transform parent,
string name )
241 if ( parent.name == name )
244 foreach ( Transform child
in parent )
246 var found = FindChild( child, name );
256 public static bool IsNullOrEmpty<T>( T[] array )
261 if ( array.Length == 0 )
269 public static bool IsValidIndex<T>( T[] array,
int i )
274 return ( i >= 0 ) && ( i < array.Length );
279 public static bool IsValidIndex<T>( List<T> list,
int i )
281 if ( list == null || list.Count == 0 )
284 return ( i >= 0 ) && ( i < list.Count );
289 public static int FindOrAdd<T>( List<T> list, T item )
291 int index = list.IndexOf( item );
296 index = list.Count - 1;
304 public static List<T> FindAndRemove<T>( List<T> list, System.Predicate<T> match )
306 List<T> retVal = list.FindAll( match );
307 list.RemoveAll( match );
313 public static T FindOrAddComponent<T>( GameObject gameObject ) where T : Component
315 T component = gameObject.GetComponent<T>();
319 return gameObject.AddComponent<T>();
324 public static void FastRemove<T>( List<T> list,
int index )
326 list[index] = list[list.Count - 1];
327 list.RemoveAt( list.Count - 1 );
332 public static void ReplaceGameObject<T, U>( T replace, U replaceWith )
333 where T : MonoBehaviour
334 where U : MonoBehaviour
336 replace.gameObject.SetActive( false );
337 replaceWith.gameObject.SetActive( true );
342 public static void SwitchLayerRecursively( Transform transform,
int fromLayer,
int toLayer )
344 if ( transform.gameObject.layer == fromLayer )
345 transform.gameObject.layer = toLayer;
347 int childCount = transform.childCount;
348 for (
int i = 0; i < childCount; i++ )
350 SwitchLayerRecursively( transform.GetChild( i ), fromLayer, toLayer );
356 public static void DrawCross( Vector3 origin, Color crossColor,
float size )
358 Vector3 line1Start = origin + ( Vector3.right * size );
359 Vector3 line1End = origin - ( Vector3.right * size );
361 Debug.DrawLine( line1Start, line1End, crossColor );
363 Vector3 line2Start = origin + ( Vector3.up * size );
364 Vector3 line2End = origin - ( Vector3.up * size );
366 Debug.DrawLine( line2Start, line2End, crossColor );
368 Vector3 line3Start = origin + ( Vector3.forward * size );
369 Vector3 line3End = origin - ( Vector3.forward * size );
371 Debug.DrawLine( line3Start, line3End, crossColor );
376 public static void ResetTransform( Transform t,
bool resetScale =
true )
378 t.localPosition = Vector3.zero;
379 t.localRotation = Quaternion.identity;
382 t.localScale =
new Vector3( 1f, 1f, 1f );
388 public static Vector3 ClosestPointOnLine( Vector3 vA, Vector3 vB, Vector3 vPoint )
390 var vVector1 = vPoint - vA;
391 var vVector2 = ( vB - vA ).normalized;
393 var d = Vector3.Distance( vA, vB );
394 var t = Vector3.Dot( vVector2, vVector1 );
402 var vVector3 = vVector2 * t;
404 var vClosestPoint = vA + vVector3;
406 return vClosestPoint;
411 public static void AfterTimer( GameObject go,
float _time, System.Action callback,
bool trigger_if_destroyed_early =
false )
413 AfterTimer_Component afterTimer_component = go.AddComponent<AfterTimer_Component>();
414 afterTimer_component.Init( _time, callback, trigger_if_destroyed_early );
419 public static void SendPhysicsMessage( Collider collider,
string message, SendMessageOptions sendMessageOptions )
421 Rigidbody rb = collider.attachedRigidbody;
422 if ( rb && rb.gameObject != collider.gameObject )
424 rb.SendMessage( message, sendMessageOptions );
427 collider.SendMessage( message, sendMessageOptions );
432 public static void SendPhysicsMessage( Collider collider,
string message,
object arg, SendMessageOptions sendMessageOptions )
434 Rigidbody rb = collider.attachedRigidbody;
435 if ( rb && rb.gameObject != collider.gameObject )
437 rb.SendMessage( message, arg, sendMessageOptions );
440 collider.SendMessage( message, arg, sendMessageOptions );
445 public static void IgnoreCollisions( GameObject goA, GameObject goB )
447 Collider[] goA_colliders = goA.GetComponentsInChildren<Collider>();
448 Collider[] goB_colliders = goB.GetComponentsInChildren<Collider>();
450 if ( goA_colliders.Length == 0 || goB_colliders.Length == 0 )
455 foreach ( Collider cA
in goA_colliders )
457 foreach ( Collider cB
in goB_colliders )
459 if ( cA.enabled && cB.enabled )
461 Physics.IgnoreCollision( cA, cB, true );
469 public static IEnumerator WrapCoroutine( IEnumerator coroutine, System.Action onCoroutineFinished )
471 while ( coroutine.MoveNext() )
473 yield
return coroutine.Current;
476 onCoroutineFinished();
481 public static Color ColorWithAlpha(
this Color color,
float alpha )
490 public static void Quit()
493 UnityEditor.EditorApplication.isPlaying =
false;
497 System.Diagnostics.Process.GetCurrentProcess().Kill();
504 public static decimal FloatToDecimal(
float value,
int decimalPlaces = 2 )
506 return Math.Round( (decimal)value, decimalPlaces );
511 public static T Median<T>(
this IEnumerable<T> source )
513 if ( source == null )
515 throw new ArgumentException(
"Argument cannot be null.",
"source" );
518 int count = source.Count();
521 throw new InvalidOperationException(
"Enumerable must contain at least one element." );
524 return source.OrderBy( x => x ).ElementAt( count / 2 );
529 public static void ForEach<T>(
this IEnumerable<T> source, Action<T> action )
531 if ( source == null )
533 throw new ArgumentException(
"Argument cannot be null.",
"source" );
536 foreach ( T value
in source )
547 public static string FixupNewlines(
string text )
549 bool newLinesRemaining =
true;
551 while ( newLinesRemaining )
553 int CIndex = text.IndexOf(
"\\n" );
557 newLinesRemaining =
false;
561 text = text.Remove( CIndex - 1, 3 );
562 text = text.Insert( CIndex - 1,
"\n" );
572 public static float PathLength( NavMeshPath path )
574 public static float PathLength( UnityEngine.AI.NavMeshPath path )
577 if ( path.corners.Length < 2 )
580 Vector3 previousCorner = path.corners[0];
581 float lengthSoFar = 0.0f;
583 while ( i < path.corners.Length )
585 Vector3 currentCorner = path.corners[i];
586 lengthSoFar += Vector3.Distance( previousCorner, currentCorner );
587 previousCorner = currentCorner;
595 public static bool HasCommandLineArgument(
string argumentName )
597 string[] args = System.Environment.GetCommandLineArgs();
598 for (
int i = 0; i < args.Length; i++ )
600 if ( args[i].Equals( argumentName ) )
611 public static int GetCommandLineArgValue(
string argumentName,
int nDefaultValue )
613 string[] args = System.Environment.GetCommandLineArgs();
614 for (
int i = 0; i < args.Length; i++ )
616 if ( args[i].Equals( argumentName ) )
618 if ( i == ( args.Length - 1 ) )
620 return nDefaultValue;
623 return System.Int32.Parse( args[i + 1] );
627 return nDefaultValue;
632 public static float GetCommandLineArgValue(
string argumentName,
float flDefaultValue )
634 string[] args = System.Environment.GetCommandLineArgs();
635 for (
int i = 0; i < args.Length; i++ )
637 if ( args[i].Equals( argumentName ) )
639 if ( i == ( args.Length - 1 ) )
641 return flDefaultValue;
644 return (
float)Double.Parse( args[i + 1] );
648 return flDefaultValue;
653 public static void SetActive( GameObject gameObject,
bool active )
655 if ( gameObject != null )
657 gameObject.SetActive( active );
667 public static string CombinePaths( params
string[] paths )
669 if ( paths.Length == 0 )
675 string combinedPath = paths[0];
676 for (
int i = 1; i < paths.Length; i++ )
678 combinedPath = Path.Combine( combinedPath, paths[i] );
690 [System.Serializable]
693 private System.Action callback;
694 private float triggerTime;
695 private bool timerActive =
false;
696 private bool triggerOnEarlyDestroy =
false;
699 public void Init(
float _time, System.Action _callback,
bool earlydestroy )
702 callback = _callback;
703 triggerOnEarlyDestroy = earlydestroy;
705 StartCoroutine( Wait() );
710 private IEnumerator Wait()
712 yield
return new WaitForSeconds( triggerTime );
725 StopCoroutine( Wait() );
728 if ( triggerOnEarlyDestroy )