using System.Collections.Generic; using UnityEngine; /// <summary> /// 绘图类 /// </summary> public class GraphicsBehaviour : MonoBehaviour { public enum PointMode { GLPoint, ScreenPoint } //private bool isOver = false; //private bool isEnd = false; [HideInInspector] public GameObject targetObj; private Material lineMaterial; void Awake() { if (targetObj == null) { targetObj = this.gameObject; } // Unity has a built-in shader that is useful for drawing // simple colored things. var shader = Shader.Find("Hidden/Internal-Colored"); lineMaterial = new Material(shader); lineMaterial.hideFlags = HideFlags.HideAndDontSave; // Turn on alpha blending lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); // Turn backface culling off lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off); // Turn off depth writes lineMaterial.SetInt("_ZWrite", 0); } private Vector2 ScreenToGLPoint(Vector2 point) { point.x /= Screen.width; point.y /= Screen.height; return point; } public void DrawLine(Vector2 start, Vector2 end, Color color, PointMode pointMode = PointMode.ScreenPoint) { if (pointMode == PointMode.ScreenPoint) { start = ScreenToGLPoint(start); end = ScreenToGLPoint(end); } GL.PushMatrix(); GL.LoadOrtho(); GL.Begin(GL.LINES); GL.Color(color); GL.Vertex(start); GL.Vertex(end); GL.End(); GL.PopMatrix(); } //3维画线 public void DrawLine3D(Vector3 start, Vector3 end, Color color) { GL.PushMatrix(); GL.Begin(GL.LINES); GL.Color(color); GL.Vertex(start); GL.Vertex(end); GL.End(); GL.PopMatrix(); } //绘制三角面(带线框) public void DrawTRIANGLES3D(Vector3 point1, Vector3 point2, Vector3 point3, Color fillColor, Color lineColor) { GL.PushMatrix(); GL.Begin(GL.TRIANGLES); GL.Color(fillColor); GL.Vertex(point1); GL.Vertex(point2); GL.Vertex(point3); GL.End(); DrawLine3D(point1, point2, lineColor); DrawLine3D(point2, point3, lineColor); DrawLine3D(point3, point1, lineColor); GL.PopMatrix(); } //绘制三角面(不带线框) public void DrawTRIANGLES3D(Vector3 point1, Vector3 point2, Vector3 point3, Color fillColor) { GL.PushMatrix(); GL.Begin(GL.TRIANGLES); GL.Color(fillColor); GL.Vertex(point1); GL.Vertex(point2); GL.Vertex(point3); GL.End(); GL.PopMatrix(); } //绘制圆面 public void DrawCirclePoly3D(int length, float radius, Vector3 centerPoint, Color fillColor) { Vector3[] CirclePoints = new Vector3[length]; for (int i = 0; i < length; i++) { float rad = Mathf.PI * 2 / length * i; Vector3 endPoint = new Vector3(centerPoint.x + Mathf.Cos(rad) * radius, centerPoint.y + Mathf.Sin(rad) * radius, centerPoint.z); CirclePoints[i] = endPoint; } //画圆面 for (int i = 0; i < CirclePoints.Length; i++) { if (i == CirclePoints.Length - 1) { DrawTRIANGLES3D(CirclePoints[i], CirclePoints[0], centerPoint, fillColor); } else { DrawTRIANGLES3D(CirclePoints[i], CirclePoints[i + 1], centerPoint, fillColor); } } } //绘制圆面(旋转) public void DrawCirclePoly3D(int length, float radius, Vector3 centerPoint, Color fillColor,Quaternion qua) { Vector3[] CirclePoints = new Vector3[length]; for (int i = 0; i < length; i++) { float rad = Mathf.PI * 2 / length * i; Vector3 endPoint = new Vector3(centerPoint.x + Mathf.Cos(rad) * radius, centerPoint.y + Mathf.Sin(rad) * radius, centerPoint.z); CirclePoints[i] = qua*endPoint; } //画圆面 for (int i = 0; i < CirclePoints.Length; i++) { if (i == CirclePoints.Length - 1) { DrawTRIANGLES3D(CirclePoints[i], CirclePoints[0], centerPoint, fillColor); } else { DrawTRIANGLES3D(CirclePoints[i], CirclePoints[i + 1], centerPoint, fillColor); } } } //绘制箭头 /// <summary> /// /// </summary> /// <param name="targetObj">目标物体</param> /// <param name="centerObj">中心点</param> /// <param name="scale">缩放倍数</param> /// <param name="color">颜色</param> public void DrawArrow(GameObject targetObj, GameObject centerObj, float scale, Color color) { Vector3 centerTotarget = targetObj.transform.position - centerObj.transform.position; //旋转四元数 Quaternion qua30 = Quaternion.AngleAxis(30, centerObj.transform.forward); Quaternion qua_30 = Quaternion.AngleAxis(-30, centerObj.transform.forward); //旋转后的向量 Vector3 lCqua30 = qua30 * centerTotarget.normalized * -1 * scale; Vector3 lCqua_30 = qua_30 * centerTotarget.normalized * -1 * scale; //旋转后的目标点 Vector3 leftqua30point = centerTotarget + lCqua30 + centerObj.transform.position; Vector3 leftqua_30point = centerTotarget + lCqua_30 + centerObj.transform.position; DrawLine3D(targetObj.transform.position, leftqua30point, color); DrawLine3D(targetObj.transform.position, leftqua_30point, color); } //绘制箭头2 public void DrawArrow2(GameObject targetObj, GameObject centerObj, float scale, Color color) { Vector3 centerTotarget = targetObj.transform.position - centerObj.transform.position; //旋转四元数 Quaternion qua30 = Quaternion.AngleAxis(30, centerObj.transform.forward); Quaternion qua_30 = Quaternion.AngleAxis(-30, centerObj.transform.forward); //旋转后的向量 Vector3 lCqua30 = qua30 * centerTotarget.normalized * scale; Vector3 lCqua_30 = qua_30 * centerTotarget.normalized * scale; //旋转后的目标点 Vector3 leftqua30point = centerObj.transform.position + lCqua30; Vector3 leftqua_30point = centerObj.transform.position + lCqua_30; DrawLine3D(centerObj.transform.position, leftqua30point, color); DrawLine3D(centerObj.transform.position, leftqua_30point, color); } //绘制箭头 public void DrawArrow(Vector3 targetPoint, Vector3 centerPoint, float scale, Color color) { Vector3 centerTotarget = targetPoint - centerPoint; //旋转四元数 Quaternion qua30 = Quaternion.AngleAxis(30, Vector3.forward); Quaternion qua_30 = Quaternion.AngleAxis(-30, Vector3.forward); //旋转后的向量 Vector3 lCqua30 = qua30 * centerTotarget.normalized * -1 * scale; Vector3 lCqua_30 = qua_30 * centerTotarget.normalized * -1 * scale; //旋转后的目标点 Vector3 leftqua30point = centerTotarget + lCqua30 + centerPoint; Vector3 leftqua_30point = centerTotarget + lCqua_30 + centerPoint; DrawLine3D(targetPoint, leftqua30point, color); DrawLine3D(targetPoint, leftqua_30point, color); } /// <summary> /// 绘制坐标轴 /// </summary> /// <param name="CenterPoint"></param> /// <param name="scale"></param> /// <param name="color"></param> public void DrawCoordinateAxis(Vector3 CenterPoint,float scale,Color color) { Vector3 xLeftPos = CenterPoint + Vector3.left*scale; Vector3 xRightPos = CenterPoint + Vector3.right*scale; Vector3 yUp = CenterPoint + Vector3.up * scale; Vector3 yDown = CenterPoint + Vector3.down * scale; DrawLine3D(xLeftPos, xRightPos, color); DrawLine3D(yUp, yDown, color); DrawArrow(xRightPos,CenterPoint,1f,color); DrawArrow(yUp, CenterPoint, 1f, color); } //绘制圆环 public void DrawCricle(int length, float radius, Vector3 centerPoint, Color color) { Vector3[] CirclePoints =new Vector3[length]; for (int i = 0; i < length; i++) { float rad = Mathf.PI*2 / length * i; Vector3 endPoint = new Vector3(centerPoint.x+Mathf.Cos(rad) * radius, centerPoint.y + Mathf.Sin(rad) * radius, centerPoint.z); CirclePoints[i] = endPoint; } for (int i = 0; i < CirclePoints.Length; i++) { if (i == CirclePoints.Length - 1) { DrawLine3D(CirclePoints[i], CirclePoints[0], color); } else { Debug.Log(CirclePoints[i]); DrawLine3D(CirclePoints[i], CirclePoints[i + 1], color); } } } //绘制圆环(旋转) public void DrawCricle(int length, float radius, Vector3 centerPoint, Color color,Quaternion qua) { Vector3[] CirclePoints = new Vector3[length]; for (int i = 0; i < length; i++) { float rad = Mathf.PI * 2 / length * i; Vector3 endPoint = new Vector3(centerPoint.x + Mathf.Cos(rad) * radius, centerPoint.y + Mathf.Sin(rad) * radius, centerPoint.z); CirclePoints[i] =qua* endPoint; } for (int i = 0; i < CirclePoints.Length; i++) { if (i == CirclePoints.Length - 1) { DrawLine3D(CirclePoints[i], CirclePoints[0], color); } else { Debug.Log(CirclePoints[i]); DrawLine3D(CirclePoints[i], CirclePoints[i + 1], color); } } } //绘制弧 public void DrawRadian( int length,Vector3 centerPoint,Vector3 startPoint, float radius, Color color) { Vector3[] CirclePoints = new Vector3[length+1]; Vector3 startVector = startPoint - centerPoint; Vector3 vt = ProjectOnPlane(startVector, Vector3.up); float angle = Vector3.Angle(vt, Vector3.right); Vector3 cross = Vector3.Cross(startVector, Vector3.right); float vtAngle = Vector3.Angle(startVector, Vector3.up); if (cross.y > 0) { angle = -angle; } Quaternion quaAngle = Quaternion.AngleAxis(angle, Vector3.up); Vector3 zhou = quaAngle * Vector3.back; if (cross.z > 0) { vtAngle = Vector3.Angle(startVector, Vector3.down); quaAngle = Quaternion.AngleAxis(-angle, Vector3.down); zhou = quaAngle * Vector3.forward; } for(int i = 0; i <= length; i++) { float rotateAngle = vtAngle / length * i; Quaternion qua = Quaternion.AngleAxis(-rotateAngle, zhou); Vector3 vCqua = qua * startVector.normalized * radius + centerPoint; CirclePoints[i] = vCqua; } for (int i = 0; i < CirclePoints.Length-1; i++) { { DrawLine3D(CirclePoints[i], CirclePoints[i + 1], color); } } } /// <summary> /// GL 平面绘制 /// </summary> /// <param name="tmpBorderPoints"></param> void DrawTriangle(List<Vector3> tmpBorderPoints) { GL.PushMatrix(); // Set transformation matrix for drawing to // match our transform GL.MultMatrix(transform.localToWorldMatrix); // Draw lines GL.Begin(GL.TRIANGLES); // Vertex colors change from red to green GL.Color(Color.green); if (tmpBorderPoints != null) { for (int i = 0; i < tmpBorderPoints.Count; i++) { if (i < tmpBorderPoints.Count - 2) { // 以第一个为原点,绘制三角形面 Vector3 posZero = tmpBorderPoints[0]; Vector3 posOne = tmpBorderPoints[i + 1]; Vector3 posTwo = tmpBorderPoints[(i + 2)]; GL.Vertex3(posZero.x, posZero.y, posZero.z); GL.Vertex3(posOne.x, posOne.y, posOne.z); GL.Vertex3(posTwo.x, posTwo.y, posTwo.z); } } } GL.End(); GL.PopMatrix(); } //向量投影 public Vector3 ProjectOnPlane(Vector3 vp, Vector3 vn) { Vector3 vt = new Vector3(); vt = vp - vn * Vector3.Dot(vp, vn) / Vector3.Dot(vn, vn); return vt; } public virtual void OnRenderObject() { lineMaterial.SetPass(0); } }