可以写一些自己需要经常调用的方法在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
}