UnityExtensions拓展方法

可以写一些自己需要经常调用的方法在UnityExtensions脚本中,方便自己的开发:

比如给物体添加脚本,顺带检测该物体是否已经挂载挂该脚本,避免重复挂载。

	static public T AddMissingComponent<T> (this GameObject go) where T : Component
	{
#if UNITY_FLASH
		object comp = go.GetComponent<T>();
#else
		T comp = go.GetComponent<T>();
#endif
		if (comp == null)
		{
#if UNITY_EDITOR
			if (!Application.isPlaying)
				RegisterUndo(go, "Add " + typeof(T));
#endif
			comp = go.AddComponent<T>();
		}
#if UNITY_FLASH
		return (T)comp;
#else
		return comp;
#endif
	}

下面附上参考脚本:可以自己增加方法

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

public static class UnityExtension
{
    static Ray ray;

    static RaycastHit hit;
    /// <summary>
    /// distanceXZ用
    /// </summary>
    static Vector2 p1, p2;

    /// <summary>
    /// 设置X,只改变X c
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="x"></param>
    static public void SetX(this Transform trans ,float x)
    {
        trans.position = new Vector3(x, trans.position.y, trans.position.z);
    }

    static public void SwitchAt(this IList list,int i1,int i2)
    {
        var tmp = list[i1];
        list[i1] = list[i2];
        list[i2] = tmp;
    }
    /// <summary>
    /// 设置Y,只改变Y c
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="x"></param>
    static public void SetY(this Transform trans, float y)
    {
        trans.position = new Vector3(trans.position.x, y, trans.position.z);
    }
    /// <summary>
    /// 设置Z,只改变Z c
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="x"></param>
    static public void SetZ(this Transform trans, float z)
    {
        trans.position = new Vector3(trans.position.x, trans.position.y, z);
    }
    /// <summary>
    /// 设置LocalX,只改变LocalX c
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="x"></param>
    static public void SetLocalX(this Transform trans, float x)
    {
        trans.localPosition = new Vector3(x, trans.localPosition.y, trans.localPosition.z);
    }
    /// <summary>
    /// 设置LocalY,只改变LocalY c
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="x"></param>
    static public void SetLocalY(this Transform trans, float y)
    {
        trans.localPosition = new Vector3(trans.localPosition.x, y, trans.localPosition.z);
    }
    /// <summary>
    /// 设置LocalZ,只改变LocalZ c
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="x"></param>
    static public void SetLocalZ(this Transform trans, float z)
    {
        trans.localPosition = new Vector3(trans.localPosition.x, trans.localPosition.y, z);
    }
    /// <summary>
    /// 在游戏中,朝向的时候只朝向某个坐标,不低头 c
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="target"></param>
    static public void LookAtXZ(this Transform trans, Vector3 target)
    {
        trans.LookAt(new Vector3(target.x,trans.position.y,target.z));
    }
    /// <summary>
    /// 遍历go c
    /// </summary>
    /// <param name="go"></param>
    /// <param name="handle"></param>
    static public void IterateGameObject(this GameObject go, Action<GameObject> handle)
    {
        Queue q = new Queue();
        q.Enqueue(go);
        while (q.Count != 0)
        {
            GameObject tmpGo = (GameObject)q.Dequeue();
            foreach (Transform t in tmpGo.transform)
            {
                q.Enqueue(t.gameObject);
            }
            if (handle != null)
            {
                handle(tmpGo);
            }
        }
    }
    /// <summary>
    /// 得到100米范围内脚下地面位置
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    static public Vector3 GetGroundPos(this Vector3 p)
    {
        if (Physics.Linecast(p + new Vector3(0, 10000f, 0), p + new Vector3(0, -10000f, 0), out hit, LayerMask.GetMask(new string[] { eLayer.Ground.ToString() })))
        {
            return new Vector3(p.x, hit.point.y + 0.03f, p.z);
        }
        return p;
    }
    /// <summary>
    /// 设置go层级关系 c
    /// </summary>
    /// <param name="go"></param>
    /// <param name="layer"></param>
    static public void SetAllLayer(this GameObject go,int layer)
    {
        IterateGameObject(go, (g) =>
        {
            g.layer = layer;
        });
    }
    /// <summary>
    /// 只返回平面距离 c
    /// </summary>
    /// <param name="pos"></param>
    /// <param name="target"></param>
    /// <returns></returns>
    static public float DistanceXZ(this Vector3 pos, Vector3 target)
    {
        p1.x = pos.x;
        p1.y = pos.z;
        p2.x = target.x;
        p2.y = target.z;
        return Vector2.Distance(p1,p2);
    }
    /// <summary>
    /// 只返回平面距离 c
    /// </summary>
    /// <param name="pos"></param>
    /// <param name="target"></param>
    /// <returns></returns>
    static public float DistanceXY(this Vector3 pos, Vector3 target)
    {
        p1.x = pos.x;
        p1.y = pos.y;
        p2.x = target.x;
        p2.y = target.y;
        return Vector2.Distance(p1, p2);
    }
    /// <summary>
    /// 重置某个物体的三围等 c
    /// </summary>
    /// <param name="go"></param>
    static public void Reset(this GameObject go)
    {
        go.transform.localPosition = Vector3.zero;
        go.transform.localScale = Vector3.one;
        go.transform.localRotation = Quaternion.Euler(0, 0, 0);
    }
    /// <summary>
    /// 给某个物体创建子物体 c
    /// </summary>
    /// <param name="go"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    static public GameObject CreateGameObject(this GameObject go,string name)
    {
        GameObject obj = new GameObject(name);
        obj.transform.parent = go.transform;
        obj.Reset();
        return obj;
    }
    /// <summary>
    /// 每一帧的移动
    /// </summary>
    /// <param name="t"></param>
    /// <param name="p"></param>
    /// <param name="speed"></param>
    static public void MoveToPerFrame(this Transform t, Vector3 p,float speed)
    {
        t.position += (p - t.position).normalized * speed * Time.deltaTime;
    }
    /// <summary>
    /// 删除某个节点下所有子物体
    /// </summary>
    /// <param name="t"></param>
    static public void DeleteAllChildren(this Transform t)
    {
        for (int i = t.childCount; i > -1; i--)
        {
            GameObject.Destroy(t.GetChild(i).gameObject);
        }
    }

    /// <summary>
    /// 将z置为负z
    /// </summary>
    /// <param name="v"></param>
    /// <returns></returns>
    static public Vector3  ReverseZ(this Vector3 v)
    {
        return new Vector3(v.x, v.y, -v.z);
    }
    /// <summary>
    /// 遍历往上寻溯Com
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="go"></param>
    /// <returns></returns>
    public static T GetComFromParent<T>(this GameObject go) where T:Component
    {
        Queue<Transform> q = new Queue<Transform>();
        q.Enqueue(go.transform);
        while (q.Count > 0)
        {
            Transform t = q.Dequeue();
            if (t.GetComponent<T>() != null)
            {
                return t.GetComponent<T>();
            }
            else
            {
                if (t.parent != null)
                {
                    q.Enqueue(t.parent);
                }
                else
                {
                    return null;
                }
            }
        }
        return null;
    }

    public static T GetParentComponent<T>(this Transform t) where T : Component
    {
        if (t.parent == null)
        {
            return null;
        }
        if (t.parent.GetComponent<T>() != null)
        {
            return t.parent.GetComponent<T>();
        }
        return GetParentComponent<T>(t.parent);
    }

	/// 重置transform
	/// 
	public static void ResetTransformView ( this Transform t ) {
		t.localPosition = Vector3.zero;
		t.localRotation = Quaternion.identity;
		t.localScale = Vector3.one;
	}
	public static Material GetMaterial ( this Renderer render ) {
#if UNITY_EDITOR
		return render.material;
#else
		return render.sharedMaterial;
#endif
	}

    #region 碰撞检测

    static public List<T> CheckInSphere<T>(this Vector3 startPos, float radius)where T:Component
    {
        List<T> list = new List<T>();
        //模拟圆形 c
        /**
        GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        obj.transform.localScale = new Vector3(radius, radius , radius );
        obj.transform.position = startPos;
        obj.GetComponent<Collider>().enabled = false;
        **/
        Collider[] colliders = Physics.OverlapSphere(startPos, radius / 2f);
        for (int i = 0; i < colliders.Length; i++)
        {
            T objCom = colliders[i].gameObject.GetComponent<T>();
            if (objCom != null)
            {
                list.Add(objCom);
            }
        }
        return list;
    }

    static public List<T> CheckInTriangle<T>(this Vector3 startPos, Vector3 endPos, float angle) where T:Component
    {
        float distance = Vector3.Distance(startPos, endPos);
        List<T> list = CheckInSphere<T>(startPos, distance * 2f);
        //
        Quaternion q = new Quaternion();
        q.SetFromToRotation(Vector3.forward, (endPos - startPos).normalized);   //置为朝向
        Quaternion r = q * Quaternion.AngleAxis(angle / 2f, Vector3.up);
        Quaternion l = q * Quaternion.AngleAxis(angle / 2f, Vector3.down);
        Vector3 lP = startPos + (l * Vector3.forward) * distance;
        Vector3 rP = startPos + (r * Vector3.forward) * distance;

        for (int i = list.Count - 1; i > -1; i--)
        {
            if (!IsINTriangle(list[i].transform.position, lP, endPos, startPos) && !IsINTriangle(list[i].transform.position, rP, endPos, startPos))
            {
                //如果在扇形外,则删除 c
                //Debug.DrawLine(startPos, endPos, Color.red);
                list.Remove(list[i]);
            }
        }
        return list;
    }


    static bool IsINTriangle(Vector3 point, Vector3 v0, Vector3 v1, Vector3 v2)
    {
        float x = point.x;
        float y = point.z;

        float v0x = v0.x;
        float v0y = v0.z;

        float v1x = v1.x;
        float v1y = v1.z;

        float v2x = v2.x;
        float v2y = v2.z;

        float t = TriangleArea(v0x, v0y, v1x, v1y, v2x, v2y);
        float a = TriangleArea(v0x, v0y, v1x, v1y, x, y) + TriangleArea(v0x, v0y, x, y, v2x, v2y) + TriangleArea(x, y, v1x, v1y, v2x, v2y);

        if (Mathf.Abs(t - a) <= 0.01f)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    static float TriangleArea(float v0x, float v0y, float v1x, float v1y, float v2x, float v2y)
    {
        return Mathf.Abs((v0x * v1y + v1x * v2y + v2x * v0y
            - v1x * v0y - v2x * v1y - v0x * v2y) / 2f);
    }

    static public List<T> CheckInRect<T>(this Vector3 startPos, Vector3 endPos, float width)where T:Component
    {
        //求敌人
        float x = Vector3.Distance(startPos, endPos);
        float radius = Mathf.Sqrt(x * x + width * width * 0.25f);
        Vector3 center = (startPos + endPos) / 2f;
        List<T> enemies = CheckInSphere<T>(center, radius * 2f);
        List<T> resultEnemies = new List<T>();
        //求范围
        Quaternion qr = Quaternion.LookRotation(endPos - startPos);

        Vector3 l = startPos + (qr * Vector3.left) * width / 2f;
        //Debug.DrawLine(startPos, l, Color.red);
        //Vector3 le = l + (qr * Vector3.forward) * x;
        //Debug.DrawLine(l, le, Color.red);
        Vector3 r = startPos + (qr * Vector3.right) * width / 2f;
        //Debug.DrawLine(startPos, r, Color.red);
        //Vector3 re = r + (qr * Vector3.forward) * x;
        //Debug.DrawLine(r, re, Color.red);
        Vector3 f = startPos + (qr * Vector3.forward) * x;
        

        for (int i = enemies.Count - 1; i > -1; i--)
        {
            Vector3 forward = (endPos - startPos).normalized;
            Vector3 toOther = enemies[i].transform.position - startPos;

            if (Vector3.Dot(forward, toOther) >= 0)
            {
                Vector3 e = enemies[i].transform.position;
                Vector3 l0e = e - l; //e到l的向量
                Vector3 r0e = e - r;//e到r的向量
                Vector3 f0e = e - f;//e到f的向量

                Vector3 h0l = startPos - l;//h到l的向量
                Vector3 h0r = startPos - r;//h到r的向量
                Vector3 h0f = startPos - f;//h到f的向量
                if (Vector3.Angle(l0e, h0l) <= 90 && Vector3.Angle(r0e, h0r) <= 90 && Vector3.Angle(f0e, h0f) <= 90)
                {
                    //enemies.RemoveAt(i);
                    resultEnemies.Add(enemies[i]);
                }
            }
        }
        return resultEnemies;
    }

    static public bool IsInArea(this Vector3 p, List<Vector3> pos)
    {
        if (pos.Count > 0)
        {
            int polygonLength = pos.Count, i = 0;
            bool inside = false;
            float pointX = p.x, pointY = p.z;
            float startX, startY, endX, endY;
            Vector3 endPoint = pos[polygonLength - 1];
            endX = endPoint.x;
            endY = endPoint.z;
            while (i < polygonLength)
            {
                startX = endX;
                startY = endY;
                endPoint = pos[i++];
                endX = endPoint.x;
                endY = endPoint.z;
                inside ^= (endY > pointY ^ startY > pointY) && ((pointX - endX) < (pointY - endY) * (startX - endX) / (startY - endY));
            }
            return inside;
        }
        else
        {
            return false;
        }
    }

    static public Vector2 IgnoreY(this Vector3 p)
    {
        return new Vector2(p.x, p.z);
    }
    /// <summary>
    /// 需要自己判断NaN
    /// </summary>
    /// <param name="p"></param>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <returns></returns>
    static public Vector3 GetVerticalPointOfLine(this Vector3 p,Vector3 p1,Vector3 p2)
    {
        float x = p2.x - p1.x;
        if (x != x || x == 0)
        {
            x = 0.01f;
        }
        float k = (p2.z - p1.z) / x;
        k = Mathf.Clamp(k, float.MinValue, float.MaxValue);
        Vector3 pProject = p;
        if (k == 0) //垂线斜率不存在情况
        {
            pProject.x = p.x;
            pProject.z = p1.z;
        }
        else
        {
            //Debug.Log("k" + k);
            //Debug.Log("(1 / k + k)" + (1 / k + k));
            pProject.x = (float)((k * p1.x + p.x / k + p.z - p1.z) / (1 / k + k));
            pProject.z = (float)(-1 / k * (pProject.x - p.x) + p.z);
        }
        return pProject;
    }

    static public Vector3 GetCenter(this List<Vector3> vets)
    {
        float x = 0, y = 0;
        for (int i = 0; i < vets.Count; i++)
        {
            x += vets[i].x;
            y += vets[i].z;
        }
        return new Vector3(x / ((float)vets.Count), vets[0].y, y / ((float)vets.Count));
    }
    #endregion
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值