本文实例为大家分享了unity实现攻击范围检测并绘制检测区域的具体代码,供大家参考,具体内容如下
一、圆形检测
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
using system.collections; using system.collections.generic; using unityengine; /// <summary> /// 圆形检测,并绘制出运行的攻击范围 /// </summary> public class circledetect : monobehaviour { gameobject go; //生成矩形的对象 public transform attack; //被攻击方 meshfilter mf; meshrenderer mr; shader shader; void start () { } void update () { if (input.getkeydown(keycode.a)) { todrawcirclesolid(transform, transform.localposition, 3); if (circleattack(attack,transform,3)) { debug.log( "攻击到了" ); } } if (input.getkeyup(keycode.a)) { if (go != null ) { destroy(go); } } } /// <summary> /// 圆形检测 /// </summary> /// <param name="attacked">被攻击者</param> /// <param name="skillpostion">技能的位置</param> /// <param name="radius">半径</param> /// <returns></returns> public bool circleattack(transform attacked, transform skillpostion, float radius) { float distance = vector3.distance(attacked.position, skillpostion.position); if (distance <= radius) { return true ; } else { return false ; } } //生成网格 public 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( "circle" ); go.transform.setparent(transform, false ); go.transform.position = new vector3(0, -0.4f, 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; } /// <summary> /// 绘制实心圆形 /// </summary> /// <param name="t">圆形参考物</param> /// <param name="center">圆心</param> /// <param name="radius">半径</param> public void todrawcirclesolid(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); } } |
效果图:
二、矩形检测
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
using system.collections; using system.collections.generic; using unityengine; /// <summary> /// 矩形型攻击检测,并绘制检测区域 /// </summary> public class drawrectangdetect : monobehaviour { public transform attacked; gameobject go; //生成矩形 meshfilter mf; meshrenderer mr; shader shader; void start () { } void update () { if (input.getkeydown(keycode.a)) { todrawrectanglesolid(transform, transform.localposition, 4, 2); if (rectattackjubge(transform, attacked, 4, 2f)) { debug.log( "攻击到" ); } } if (input.getkeyup(keycode.a)) { if (go != null ) { destroy(go); } } } /// <summary> /// 矩形攻击范围 /// </summary> /// <param name="attacker">攻击方</param> /// <param name="attacked">被攻击方</param> /// <param name="forwarddistance">矩形前方的距离</param> /// <param name="rightdistance">矩形宽度/2</param> /// <returns></returns> public bool rectattackjubge(transform attacker, transform attacked, float forwarddistance, float rightdistance) { vector3 deltaa = attacked.position - attacker.position; float forwarddota = vector3.dot(attacker.forward, deltaa); if (forwarddota > 0 && forwarddota <= forwarddistance) { if (mathf.abs(vector3.dot(attacker.right,deltaa)) < rightdistance) { return true ; } } return false ; } //制作网格 private 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 * 1] = 0; triangles[3 * i + 1] = i + 1; triangles[3 * i + 2] = i + 2; } if (go == null ) { go = new gameobject( "rectang" ); 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; } /// <summary> /// 绘制实心长方形 /// </summary> /// <param name="t">矩形参考物</param> /// <param name="bottommiddle">矩形的中心点</param> /// <param name="length">矩形长度</param> /// <param name="width">矩形宽度的一半</param> public void todrawrectanglesolid(transform t, vector3 bottommiddle, float length, float width) { list<vector3> vertices = new list<vector3>(); vertices.add(bottommiddle - t.right * width); vertices.add(bottommiddle - t.right * width + t.forward * length); vertices.add(bottommiddle + t.right * width + t.forward * length); vertices.add(bottommiddle + t.right * width ); createmesh(vertices); } } |
效果图:
三、扇形攻击检测
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
using system.collections; using system.collections.generic; using unityengine; /// <summary> /// 扇型攻击检测,并绘制检测区域 /// </summary> public class sectordetect : monobehaviour { public transform attacked; //受攻击着 gameobject go; meshfilter mf; meshrenderer mr; shader shader; void start () { } void update () { if (input.getkeydown(keycode.a)) { todrawsectorsolid(transform, transform.localposition, 60, 3); if (umbrellaattact(transform,attacked.transform,60,4)) { debug.log( "受攻击了" ); } } if (input.getkeyup(keycode.a)) { if (go != null ) { destroy(go); } } } /// <summary> /// 扇形攻击范围 /// </summary> /// <param name="attacker">攻击者</param> /// <param name="attacked">被攻击方</param> /// <param name="angle">扇形角度</param> /// <param name="radius">扇形半径</param> /// <returns></returns> public bool umbrellaattact(transform attacker, transform attacked, float angle, float radius) { vector3 deltaa = attacked.position - attacker.position; //mathf.rad2deg : 弧度值到度转换常度 //mathf.acos(f) : 返回参数f的反余弦值 float tmpangle = mathf.acos(vector3.dot(deltaa.normalized, attacker.forward)) * mathf.rad2deg; if (tmpangle < angle * 0.5f && deltaa.magnitude < radius) { return true ; } return false ; } public void todrawsectorsolid(transform t, vector3 center, float angle, float radius) { int pointammount = 100; float eachangle = angle / pointammount; vector3 forward = t.forward; list<vector3> vertices = new list<vector3>(); vertices.add(center); for ( int i = 0; i < pointammount; i++) { vector3 pos = quaternion.euler(0f, -angle / 2 + eachangle * (i - 1), 0f) * forward * radius + center; vertices.add(pos); } createmesh(vertices); } private 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(0f, 0.1f, 0.5f); 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; } } |
效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_38721111/article/details/86742317