[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
- [Unity实战]攻击范围的绘制
- [Unity实战]攻击范围的绘制
- [Unity实战]虚线的绘制
- Unity_Shader_用Shader绘制攻击范围的圆圈
- Unity一个智能火力点,根据攻击范围自动旋转攻击
- Unity一个智能火力点,根据攻击范围自动旋转攻击
- Unity Assetbundle的实战
- Unity Inspector的简单绘制
- Unity实现炮弹的爆炸范围
- {Unity} Renderer SortingOrder的取值范围
- unity 人物碰撞范围的动态修改
- unity 球形范围的爆炸效果
- Unity3D 攻击范围检测
- 进入攻击范围
- 敌人进入攻击范围
- 解决大范围SQL注入攻击的问题
- 一次真实的DDoS攻击防御实战
- Unity 绘制人物头顶的血条
- linux daemon简介
- leetcode--69.sqrt(x)
- IOS- uitextviewdemo
- python: 选择排序
- 本机socket通信(Java
- [Unity实战]攻击范围的绘制
- hdu2242考研路茫茫——空调教室(边双连通,缩点,dfs)
- uiviewcontroller 转场放大缩小动画
- 如何让你的魅蓝手机无网络下GPS神速搜星定位!
- 用java连数据库怎么都连不上,才发现SQL server开启TCP/IP登录,并且启用默认的1433端口
- HTML5之embed 播放音频
- 微信6.0界面学习笔记
- leetcode31---Next Permutation
- 逆向工程 0x01