using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; namespace Beyond { public static class Extensions { public static bool IsAncestor(this Transform trans, Transform ancestor) { if (trans.parent == null) return false; if (trans.parent == ancestor) return true; return trans.parent.IsAncestor(ancestor); } public static void SetLayer(this Transform trans, int layer) { trans.gameObject.layer = layer; foreach (Transform child in trans) child.SetLayer(layer); } /* public static List FindComponentsDownHierarchy(this GameObject g) where T : Component { List result = new List(); T component; component = g.GetComponent(); if (component == null) component = g.GetComponentInChildren(); return component; } */ public static T FindComponentDownHierarchy(this GameObject g) where T : Component { T component; component = g.GetComponent(); if (component == null) component = g.GetComponentInChildren(); return component; } public static T FindComponentUpHierarchy(this GameObject g) where T : Component { T component; component = g.GetComponent(); if (component == null && g.transform.parent != null) { component = FindComponentUpHierarchy(g.transform.parent.gameObject); } return component; } public static void EnableRendererRecursivly(this GameObject g, bool enable) { g.GetComponent().enabled = enable; for (int i = 0; i < g.transform.childCount; i++) { EnableRendererRecursivly(g.transform.GetChild(i).gameObject, enable); } } public static T[] GetAllObjectsOnlyInScene() where T : MonoBehaviour { #if UNITY_EDITOR List objectsInScene = new List(); foreach (T go in Resources.FindObjectsOfTypeAll(typeof(T)) as T[]) { if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave)) objectsInScene.Add(go); } return objectsInScene.ToArray(); #else return Resources.FindObjectsOfTypeAll(typeof(T)) as T[]; #endif } } public static class Vector2Extension { // positive if v2 is on the left side of v1 public static float SignedAngle(this Vector2 v1, Vector2 v2) { Vector2 n1 = v1.normalized; Vector2 n2 = v2.normalized; float dot = Vector2.Dot(n1, n2); if (dot > 1.0f) dot = 1.0f; if (dot < -1.0f) dot = -1.0f; float theta = Mathf.Acos(dot); float sgn = Vector2.Dot(new Vector2(-n1.y, n1.x), n2); if (sgn >= 0f) return theta; else return -theta; } public static Vector2 Rotate(this Vector2 v, float theta) { float cs = Mathf.Cos(theta); float sn = Mathf.Sin(theta); float x1 = v.x * cs - v.y * sn; float y1 = v.x * sn + v.y * cs; return new Vector2(x1, y1); } } public static class Vector3Extension { public static Vector3 WithX(this Vector3 v, float x) { return new Vector3(x, v.y, v.z); } public static Vector3 WithY(this Vector3 v, float y) { return new Vector3(v.x, y, v.z); } public static Vector3 WithZ(this Vector3 v, float z) { return new Vector3(v.x, v.y, z); } } public static class Matrix4x4Extension { public static Matrix4x4 GetPerspectiveProjection(float left, float right, float bottom, float top, float near, float far) { float x = (2.0f * near) / (right - left); float y = (2.0f * near) / (top - bottom); float a = (right + left) / (right - left); float b = (top + bottom) / (top - bottom); float c = -(far + near) / (far - near); float d = -(2.0f * far * near) / (far - near); float e = -1.0f; Matrix4x4 m = new Matrix4x4(); m[0, 0] = x; m[0, 1] = 0; m[0, 2] = a; m[0, 3] = 0; m[1, 0] = 0; m[1, 1] = y; m[1, 2] = b; m[1, 3] = 0; m[2, 0] = 0; m[2, 1] = 0; m[2, 2] = c; m[2, 3] = d; m[3, 0] = 0; m[3, 1] = 0; m[3, 2] = e; m[3, 3] = 0; return m; } } public static class GameObjectExt { public static void SetLayerRecursively(this GameObject obj, int layer) { obj.layer = layer; foreach (Transform t in obj.transform) { t.gameObject.SetLayerRecursively(layer); } } } public static class QuaternionExt { public static Quaternion Mul(this Quaternion quat, float a) { Quaternion res = quat; res.x *= a; res.y *= a; res.z *= a; res.w *= a; return res; } public static Quaternion Normalize(this Quaternion quat) { float s = Mathf.Sqrt(quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w); return quat.Mul(1.0f / s); } public static Quaternion Add(this Quaternion lhs, Quaternion rhs) { Quaternion res = lhs; res.x += rhs.x; res.y += rhs.y; res.z += rhs.z; res.w += rhs.w; return res; } } public static class CameraExtension { public static Matrix4x4 GetPerspectiveProjection(this Camera camera) { return GetPerspectiveProjection(camera, 0f, 0f); } public static Matrix4x4 GetPerspectiveProjection(this Camera camera, float texelOffsetX, float texelOffsetY) { if (camera == null) return Matrix4x4.identity; float oneExtentY = Mathf.Tan(0.5f * Mathf.Deg2Rad * camera.fieldOfView); float oneExtentX = oneExtentY * camera.aspect; float texelSizeX = oneExtentX / (0.5f * camera.pixelWidth); float texelSizeY = oneExtentY / (0.5f * camera.pixelHeight); float oneJitterX = texelSizeX * texelOffsetX; float oneJitterY = texelSizeY * texelOffsetY; float cf = camera.farClipPlane; float cn = camera.nearClipPlane; float xm = (oneJitterX - oneExtentX) * cn; float xp = (oneJitterX + oneExtentX) * cn; float ym = (oneJitterY - oneExtentY) * cn; float yp = (oneJitterY + oneExtentY) * cn; return Matrix4x4Extension.GetPerspectiveProjection(xm, xp, ym, yp, cn, cf); } public static Vector4 GetPerspectiveProjectionCornerRay(this Camera camera) { return GetPerspectiveProjectionCornerRay(camera, 0f, 0f); } public static Vector4 GetPerspectiveProjectionCornerRay(this Camera camera, float texelOffsetX, float texelOffsetY) { if (camera == null) return Vector4.zero; float oneExtentY = Mathf.Tan(0.5f * Mathf.Deg2Rad * camera.fieldOfView); float oneExtentX = oneExtentY * camera.aspect; float texelSizeX = oneExtentX / (0.5f * camera.pixelWidth); float texelSizeY = oneExtentY / (0.5f * camera.pixelHeight); float oneJitterX = texelSizeX * texelOffsetX; float oneJitterY = texelSizeY * texelOffsetY; return new Vector4(oneExtentX, oneExtentY, oneJitterX, oneJitterY); } } }