[Unity实战]攻击范围的绘制

来源:互联网 发布:windows错误报告 进程 编辑:程序博客网 时间:2024/06/07 02:42

效果图:












代码如下:

using UnityEngine;using System.Collections.Generic;public class DrawTool : MonoBehaviour {    private static LineRenderer GetLineRenderer(Transform t)    {        LineRenderer lr = t.GetComponent<LineRenderer>();        if (lr == null)        {            lr = t.gameObject.AddComponent<LineRenderer>();        }        lr.SetWidth(0.1f, 0.1f);        return lr;    }    public static void DrawLine(Transform t, Vector3 start, Vector3 end)    {        LineRenderer lr = GetLineRenderer(t);        lr.SetVertexCount(2);        lr.SetPosition(0, start);        lr.SetPosition(1, end);    }    //绘制空心扇形      public static void DrawSector(Transform t, Vector3 center, float angle, float radius)    {        LineRenderer lr = GetLineRenderer(t);        int pointAmount = 100;//点的数目,值越大曲线越平滑          float eachAngle = angle / pointAmount;        Vector3 forward = t.forward;        lr.SetVertexCount(pointAmount);        lr.SetPosition(0, center);        lr.SetPosition(pointAmount - 1, center);        for (int i = 1; i < pointAmount - 1; i++)        {            Vector3 pos = Quaternion.Euler(0f, -angle / 2 + eachAngle * (i - 1), 0f) * forward * radius + center;            lr.SetPosition(i, pos);        }    }    //绘制空心圆      public static void DrawCircle(Transform t, Vector3 center, float radius)    {        LineRenderer lr = GetLineRenderer(t);        int pointAmount = 100;//点的数目,值越大曲线越平滑          float eachAngle = 360f / pointAmount;        Vector3 forward = t.forward;        lr.SetVertexCount(pointAmount + 1);        for (int i = 0; i <= pointAmount; i++)        {            Vector3 pos = Quaternion.Euler(0f, eachAngle * i, 0f) * forward * radius + center;            lr.SetPosition(i, pos);        }    }    //绘制空心长方形    //以长方形的底边中点为攻击方位置(从俯视角度来看)    public static void DrawRectangle(Transform t, Vector3 bottomMiddle, float length, float width)    {        LineRenderer lr = GetLineRenderer(t);        lr.SetVertexCount(5);        lr.SetPosition(0, bottomMiddle - t.right * (width / 2));        lr.SetPosition(1, bottomMiddle - t.right * (width / 2) + t.forward * length);        lr.SetPosition(2, bottomMiddle + t.right * (width / 2) + t.forward * length);        lr.SetPosition(3, bottomMiddle + t.right * (width / 2));        lr.SetPosition(4, bottomMiddle - t.right * (width / 2));    }    //绘制空心长方形2D    //distance指的是这个长方形与Transform t的中心点的距离    public static void DrawRectangle2D(Transform t, float distance, float length, float width)    {        LineRenderer lr = GetLineRenderer(t);        lr.SetVertexCount(5);        if (MathTool.IsFacingRight(t))        {            Vector2 forwardMiddle = new Vector2(t.position.x + distance, t.position.y);            lr.SetPosition(0, forwardMiddle + new Vector2(0, width / 2));            lr.SetPosition(1, forwardMiddle + new Vector2(length, width / 2));            lr.SetPosition(2, forwardMiddle + new Vector2(length, -width / 2));            lr.SetPosition(3, forwardMiddle + new Vector2(0, -width / 2));            lr.SetPosition(4, forwardMiddle + new Vector2(0, width / 2));        }        else        {            Vector2 forwardMiddle = new Vector2(t.position.x - distance, t.position.y);            lr.SetPosition(0, forwardMiddle + new Vector2(0, width / 2));            lr.SetPosition(1, forwardMiddle + new Vector2(-length, width / 2));            lr.SetPosition(2, forwardMiddle + new Vector2(-length, -width / 2));            lr.SetPosition(3, forwardMiddle + new Vector2(0, -width / 2));            lr.SetPosition(4, forwardMiddle + new Vector2(0, width / 2));        }    }    public static GameObject go;    public static MeshFilter mf;    public static MeshRenderer mr;    public static Shader shader;    private static GameObject CreateMesh(List<Vector3> vertices)    {        int[] triangles;        Mesh mesh = new Mesh();        int triangleAmount = vertices.Count - 2;        triangles = new int[3 * triangleAmount];        //根据三角形的个数,来计算绘制三角形的顶点顺序(索引)            //顺序必须为顺时针或者逆时针            for (int i = 0; i < triangleAmount; i++)        {            triangles[3 * i] = 0;//固定第一个点                triangles[3 * i + 1] = i + 1;            triangles[3 * i + 2] = i + 2;        }        if (go == null)        {            go = new GameObject("mesh");            go.transform.position = new Vector3(0, 0.1f, 0);//让绘制的图形上升一点,防止被地面遮挡            mf = go.AddComponent<MeshFilter>();            mr = go.AddComponent<MeshRenderer>();            shader = Shader.Find("Unlit/Color");        }        mesh.vertices = vertices.ToArray();        mesh.triangles = triangles;        mf.mesh = mesh;        mr.material.shader = shader;        mr.material.color = Color.red;           return go;    }    //绘制实心扇形      public static void DrawSectorSolid(Transform t, Vector3 center, float angle, float radius)    {        int pointAmount = 100;//点的数目,值越大曲线越平滑          float eachAngle = angle / pointAmount;        Vector3 forward = t.forward;        List<Vector3> vertices = new List<Vector3>();        vertices.Add(center);        for (int i = 1; i < pointAmount - 1; i++)        {            Vector3 pos = Quaternion.Euler(0f, -angle / 2 + eachAngle * (i - 1), 0f) * forward * radius + center;            vertices.Add(pos);        }        CreateMesh(vertices);    }    //绘制实心圆      public static void DrawCircleSolid(Transform t, Vector3 center, float radius)    {        int pointAmount = 100;//点的数目,值越大曲线越平滑          float eachAngle = 360f / pointAmount;        Vector3 forward = t.forward;        List<Vector3> vertices = new List<Vector3>();        for (int i = 0; i <= pointAmount; i++)        {            Vector3 pos = Quaternion.Euler(0f, eachAngle * i, 0f) * forward * radius + center;            vertices.Add(pos);        }        CreateMesh(vertices);    }    //绘制实心长方形    //以长方形的底边中点为攻击方位置(从俯视角度来看)    public static void DrawRectangleSolid(Transform t, Vector3 bottomMiddle, float length, float width)    {        List<Vector3> vertices = new List<Vector3>();        vertices.Add(bottomMiddle - t.right * (width / 2));        vertices.Add(bottomMiddle - t.right * (width / 2) + t.forward * length);        vertices.Add(bottomMiddle + t.right * (width / 2) + t.forward * length);        vertices.Add(bottomMiddle + t.right * (width / 2));        CreateMesh(vertices);    }    //绘制实心长方形2D    //distance指的是这个长方形与Transform t的中心点的距离    public static void DrawRectangleSolid2D(Transform t, float distance, float length, float width)    {        List<Vector3> vertices = new List<Vector3>();        if (MathTool.IsFacingRight(t))        {            Vector3 forwardMiddle = new Vector3(t.position.x + distance, t.position.y);            vertices.Add(forwardMiddle + new Vector3(0, width / 2));            vertices.Add(forwardMiddle + new Vector3(length, width / 2));            vertices.Add(forwardMiddle + new Vector3(length, -width / 2));            vertices.Add(forwardMiddle + new Vector3(0, -width / 2));        }        else        {            //看不到颜色但点击mesh可以看到形状            Vector3 forwardMiddle = new Vector3(t.position.x - distance, t.position.y);            vertices.Add(forwardMiddle + new Vector3(0, width / 2));            vertices.Add(forwardMiddle + new Vector3(-length, width / 2));            vertices.Add(forwardMiddle + new Vector3(-length, -width / 2));            vertices.Add(forwardMiddle + new Vector3(0, -width / 2));        }        CreateMesh(vertices);    }}


测试:

using UnityEngine;using System.Collections;public class TestDraw : MonoBehaviour {void Start ()     {        //DrawTool.DrawSector(transform, transform.localPosition, 60, 3);        //DrawTool.DrawCircle(transform, transform.localPosition, 3);        //DrawTool.DrawRectangle(transform, transform.localPosition, 5, 2);        //DrawTool.DrawSectorSolid(transform, transform.localPosition, 60, 3);        //DrawTool.DrawCircleSolid(transform, transform.localPosition, 3);        DrawTool.DrawRectangleSolid(transform, transform.localPosition, 5, 2);}}

然后,为了更好地测试数据,应该要有这样一个东西:


using UnityEngine;using System.Collections;public enum DrawType{    DrawSector,              //绘制空心扇形    DrawCircle,              //绘制空心圆    DrawRectangle,           //绘制空心长方形    DrawRectangle2D,         //绘制空心长方形2D    DrawSectorSolid,         //绘制实心扇形    DrawCircleSolid,         //绘制实心圆    DrawRectangleSolid,      //绘制实心长方形    DrawRectangleSolid2D,    //绘制实心长方形2D}/// <summary>/// 要把动画上的脚本(继承StateMachineBehaviour)取消勾选/// </summary>public class DebugDistanceAngle : MonoBehaviour {    private GameObject go;    private Animator animator;    public string modelName;//角色路径    public string animationName;//动画名字,即Animator窗口看到的动画名字    public float time;//播放进度    public DrawType drawType;    public float distance;    public float angle;    public float radius;    public float length;    public float width;void Start ()     {        if (modelName.Length > 0)        {            go = Instantiate(Resources.Load<GameObject>(modelName));            go.transform.localPosition = Vector3.zero;            animator = go.GetComponent<Animator>();        }}void Update ()     {        if ((go != null) && (time != 0))        {            animator.Play(animationName, 0, time);         }        switch (drawType)        {            case DrawType.DrawSector :                DrawTool.DrawSector(go.transform, go.transform.position, angle, radius);                break;            case DrawType.DrawCircle:                DrawTool.DrawCircle(go.transform, go.transform.position, radius);                break;            case DrawType.DrawRectangle:                DrawTool.DrawRectangle(go.transform, go.transform.position, length, width);                break;            case DrawType.DrawRectangle2D:                DrawTool.DrawRectangle2D(go.transform, distance, length, width);                break;            case DrawType.DrawSectorSolid:                DrawTool.DrawSectorSolid(go.transform, go.transform.position, angle, radius);                break;            case DrawType.DrawCircleSolid:                DrawTool.DrawCircleSolid(go.transform, go.transform.position, radius);                break;            case DrawType.DrawRectangleSolid:                DrawTool.DrawRectangleSolid(go.transform, go.transform.position, length, width);                break;            case DrawType.DrawRectangleSolid2D:                DrawTool.DrawRectangleSolid2D(go.transform, distance, length, width);                break;            default :                break;        }}}

using UnityEngine;using System.Collections;using UnityEditor;[CustomEditor(typeof(DebugDistanceAngle))][ExecuteInEditMode]public class DebugDistanceAngleEditor : Editor {    private bool canGetDragEvent;    public override void OnInspectorGUI()    {        DebugDistanceAngle d = target as DebugDistanceAngle;        EditorGUILayout.LabelField("请把角色放在Resources文件夹中,点击Play之后将通过Resources进行加载");        canGetDragEvent = EditorGUILayout.Toggle("通过拖拽获取角色路径", canGetDragEvent);        EditorGUILayout.LabelField("角色路径");        if (canGetDragEvent)        {            if (Event.current.type == EventType.DragExited)            {                if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0)                {                    string s = DragAndDrop.paths[0];                    s = s.Substring(s.IndexOf("Resources/"));                     s = s.Remove(0, "Resources/".Length);                    s = s.Substring(0, s.IndexOf('.'));                    d.modelName = s;                }            }        }        d.modelName = EditorGUILayout.TextArea(d.modelName);        d.animationName = EditorGUILayout.TextField("动画名字", d.animationName);        EditorGUILayout.LabelField("播放进度");        d.time = EditorGUILayout.Slider(d.time, 0, 1);        d.drawType = (DrawType)EditorGUILayout.EnumPopup("绘制类型" ,d.drawType);        switch (d.drawType)        {            case DrawType.DrawSector:                EditorGUILayout.LabelField("绘制空心扇形");                EditorGUILayout.LabelField("角度");                d.angle = EditorGUILayout.Slider(d.angle, 0, 180);                EditorGUILayout.LabelField("半径");                d.radius = EditorGUILayout.Slider(d.radius, 0, 10);                break;            case DrawType.DrawCircle:                EditorGUILayout.LabelField("绘制空心圆");                EditorGUILayout.LabelField("半径");                d.radius = EditorGUILayout.Slider(d.radius, 0, 10);                break;            case DrawType.DrawRectangle:                EditorGUILayout.LabelField("绘制空心长方形");                EditorGUILayout.LabelField("长度");                d.length = EditorGUILayout.Slider(d.length, 0, 10);                EditorGUILayout.LabelField("宽度");                d.width = EditorGUILayout.Slider(d.width, 0, 10);                break;            case DrawType.DrawRectangle2D:                EditorGUILayout.LabelField("绘制空心长方形2D");                EditorGUILayout.LabelField("距离");                d.distance = EditorGUILayout.Slider(d.distance, 0, 10);                EditorGUILayout.LabelField("长度");                d.length = EditorGUILayout.Slider(d.length, 0, 10);                EditorGUILayout.LabelField("宽度");                d.width = EditorGUILayout.Slider(d.width, 0, 10);                break;            case DrawType.DrawSectorSolid:                EditorGUILayout.LabelField("绘制实心扇形");                EditorGUILayout.LabelField("角度");                d.angle = EditorGUILayout.Slider(d.angle, 0, 180);                EditorGUILayout.LabelField("半径");                d.radius = EditorGUILayout.Slider(d.radius, 0, 10);                break;            case DrawType.DrawCircleSolid:                EditorGUILayout.LabelField("绘制实心圆");                EditorGUILayout.LabelField("半径");                d.radius = EditorGUILayout.Slider(d.radius, 0, 10);                break;            case DrawType.DrawRectangleSolid:                EditorGUILayout.LabelField("绘制实心长方形");                EditorGUILayout.LabelField("长度");                d.length = EditorGUILayout.Slider(d.length, 0, 10);                EditorGUILayout.LabelField("宽度");                d.width = EditorGUILayout.Slider(d.width, 0, 10);                break;            case DrawType.DrawRectangleSolid2D:                EditorGUILayout.LabelField("绘制实心长方形2D");                EditorGUILayout.LabelField("距离");                d.distance = EditorGUILayout.Slider(d.distance, 0, 10);                EditorGUILayout.LabelField("长度");                d.length = EditorGUILayout.Slider(d.length, 0, 10);                EditorGUILayout.LabelField("宽度");                d.width = EditorGUILayout.Slider(d.width, 0, 10);                break;            default:                break;        }    }}



using UnityEngine;using System.Collections;public class MathTool {    public static float piDivide180 = Mathf.PI / 180;    public static bool IsFacingRight(Transform t)    {        if (t.localEulerAngles.y > 0) return false;        else return true;    }    public static void FacingRight(Transform t)    {        t.localEulerAngles = new Vector3(0, 0, 0);    }    public static void FacingLeft(Transform t)    {        t.localEulerAngles = new Vector3(0, 180, 0);    }    public static Vector2 GetVector2(Vector3 a)    {        Vector2 posA = new Vector2(a.x, a.z);        return posA;    }    public static float GetDistance(Transform a, Transform b)    {        Vector2 posA = GetVector2(a.position);        Vector2 posB = GetVector2(b.position);        return Vector2.Distance(posA, posB);    }    public static Vector2 GetDirection(Transform a, Transform b)    {        Vector2 posA = GetVector2(a.position);        Vector2 posB = GetVector2(b.position);        return posB - posA;    }}



2 0
原创粉丝点击