using System; using System.Collections.Generic; using BindingFlags = System.Reflection.BindingFlags; using UnityEngine; using System.Collections; using GatherAndDefend.LevelEditor; using System.Linq; using System.Threading.Tasks; public static class Extensions { public static async Task WaitWhile(Func toKeepTrue) { while (toKeepTrue?.Invoke() == true) { await Task.Yield(); } } public static T[] GetAllComponents(this Component component) where T : Component { List comps = new List(); comps.AddRange(component.GetComponents()); comps.AddRange(component.GetComponentsInChildren()); return comps.ToArray(); } public static Rect CalculateBounds(this Level level) { Rect bound = new Rect(0, 0, 0, 0); foreach (var tilemap in level) { foreach (var tile in tilemap) { bound = bound.GetUpdatedBound((Vector3)tile.Position); } } return bound; } public static Rect GetUpdatedBound(this Rect bound, Rect other) { var rect = bound; rect.xMin = other.xMin < rect.xMin ? other.xMin : rect.xMin; rect.yMin = other.yMin < rect.yMin ? other.yMin : rect.yMin; rect.xMax = other.xMax > rect.xMax ? other.xMax : rect.xMax; rect.yMax = other.yMax > rect.yMax ? other.yMax : rect.yMax; return rect; } public static Rect GetUpdatedBound(this Rect bound, Vector2 position) { var rect = bound; rect.xMin = position.x < rect.xMin ? position.x : rect.xMin; rect.yMin = position.y < rect.yMin ? position.y : rect.yMin; rect.xMax = position.x > rect.xMax ? position.x : rect.xMax; rect.yMax = position.y > rect.yMax ? position.y : rect.yMax; return rect; } public static int ToInt(this object jobj) { return int.Parse(jobj.ToString()); } public static float ToFloat(this object jobj) { return float.Parse(jobj.ToString()); } public static Vector3 ToVector3(this object jobj) { var p_enum = (jobj as IEnumerable).GetEnumerator(); float[] p_array = new float[3]; p_enum.MoveNext(); p_array[0] = float.Parse(p_enum.Current.ToString()); p_enum.MoveNext(); p_array[1] = float.Parse(p_enum.Current.ToString()); p_enum.MoveNext(); p_array[2] = float.Parse(p_enum.Current.ToString()); return new Vector3(p_array[0], p_array[1], p_array[2]); } public static bool ToBool(this object jobj) => bool.Parse(jobj.ToString()); public static GameObject Create(this GameObject prefab, Vector3 position, Quaternion rotation = default, Transform parent = null) { if (rotation == default) rotation = Quaternion.identity; var instance = GameObject.Instantiate(prefab, position, rotation); instance.transform.SetParent(parent); instance.name = prefab.name; return instance; } public static T GetComponentInChildren(this Component obj, string name) where T : Component { foreach (var comp in obj.GetComponentsInChildren()) { if (comp.name == name) return comp; } return null; } public enum LevelObjectType { GameObject, Tile } /// /// check if an object is positioned on the same postion as an other (with a size 1 buffer) /// /// /// /// public static bool IsContainedIn(this Vector3 vect, Vector3 tilePosition) { return Vector2.Distance(vect, tilePosition) < 0.5f; } public static Vector2 RandomInRectangle(float x, float y) { var randX = UnityEngine.Random.Range(0, x); var randY = UnityEngine.Random.Range(0, y); return new Vector2(randX, randY); } public static T Minimum(this IEnumerable list, Func func) { if (list.Count() < 1) throw new Exception("in " + nameof(Minimum) + " : Cannot find minimum of empty list : " + nameof(list)); T minT = list.ElementAt(0); float minVal = func(minT); foreach (var obj in list) { var newVal = func(obj); if (minVal > newVal) { minT = obj; minVal = newVal; } } return minT; } public static IEnumerator FadeTo(this CanvasGroup item, float value, float duration) { var delta = value - item.alpha; var direction = Mathf.Sign(delta); while (Mathf.Abs(value - item.alpha) > 0) { item.alpha += Time.deltaTime * direction / duration; yield return null; } item.alpha = value; } }