zl程序教程

您现在的位置是:首页 >  其他

当前栏目

游戏开发中的数学问题:技能伤害的区域检测(方形)

2023-03-07 09:52:06 时间

不管技能的特效有多炫酷,在背后都是规规矩矩的范围判断.矩形是范围判断中最简单的一种.首先,只要知道对角的两个点,就可以判断出敌人是否是在这个矩形范围内了.为什么呢?因为在游戏开发过程中,技能一般是在地面上的,那么.就确定这两个点是在这个平面上.然后对角的两个点可以把另一个对角的点确定出来.

首先,我们通过2个已知的点确定一个矩形,我们需要一个Rectangle的类,用来获取4个点和判断某个点是否在矩形内.

首先是通过2个已知点得出其他的两个点:

 1using System.Collections;
 2using System.Collections.Generic;
 3using UnityEngine;
 4
 5public class Rectangle
 6{
 7
 8    public Vector3 corner1;//四边形的一个对角位置
 9    public Vector3 corner2;//四边形的另一个对角位置
10
11    //获得四个角顶点
12    public void GetVerts(out Vector3 vertex0, out Vector3 vertex1, out Vector3 vertex2, out Vector3 vertex3)
13    {
14        vertex0 = this.corner1;
15        vertex1 = new Vector3(this.corner2.x, 0, this.corner1.z);
16        vertex2 = this.corner2;
17        vertex3 = new Vector3(this.corner1.x, 0, this.corner2.z);
18    }
19}

我们就通过这个方法,获得矩形的4个点,来画出矩形的区域:

1using System.Collections;
 2using System.Collections.Generic;
 3using UnityEngine;
 4
 5public class TestRt : MonoBehaviour
 6{
 7
 8    //public Transform Point;
 9    public Transform RtPoint0, RtPoint1;
10    public Rectangle rtBox;
11
12    private const float _pointRadius = 0.1f;
13
14    private void OnDrawGizmos()
15    {
16        rtBox = CreateFromTwoPoints(RtPoint0.position, RtPoint1.position);
17
18        if (rtBox != null)
19        {
20            DrawFrameLine(rtBox); 
21        }
22    }
23
24    public Rectangle CreateFromTwoPoints(Vector3 point0, Vector3 point1)
25    {
26        Rectangle rt = new Rectangle();
27        if (point0.x < point1.x)
28        {
29            rt.corner1.x = point0.x;
30            rt.corner2.x = point1.x;
31        }
32        else
33        {
34            rt.corner1.x = point1.x;
35            rt.corner2.x = point0.x;
36        }
37        if (point0.z < point1.z)
38        {
39            rt.corner1.z = point0.z;
40            rt.corner2.z = point1.z;
41        }
42        else
43        {
44            rt.corner1.z = point1.z;
45            rt.corner2.z = point0.z;
46        }
47        return rt;
48    }
49
50    protected void DrawFrameLine(Rectangle box)
51    {
52        Vector3 v0, v1, v2, v3;
53        box.GetVerts(out v0, out v1, out v2, out v3);  
54        Gizmos.DrawLine(v0, v1);
55        Gizmos.DrawLine(v1, v2);
56        Gizmos.DrawLine(v2, v3);
57        Gizmos.DrawLine(v3, v0);
58    }
59}

然后对2个点进行赋值,注意,Y轴要为0,因为我们规定的平面是xz平面.那么我们看看画出的效果:

判断就更为简单了,同样的这个点的Y轴要为0.我们做个这样的功能,当这个点在矩形范围内的时候,框变红,如果不在,框为蓝色:

 1using System.Collections;
 2using System.Collections.Generic;
 3using UnityEngine;
 4
 5public class TestRt : MonoBehaviour
 6{
 7
 8    public Transform Point;
 9    public Transform RtPoint0, RtPoint1;
10    public Rectangle rtBox;
11
12    private const float _pointRadius = 0.1f;
13
14    private void OnDrawGizmos()
15    {
16        rtBox = CreateFromTwoPoints(RtPoint0.position, RtPoint1.position);
17        bool cont = rtBox.CheckisInzone(Point.position);
18        if (cont)
19        {
20            Gizmos.color = Color.red; 
21        }
22        else
23        {
24            Gizmos.color = Color.blue; 
25        }
26
27        if (rtBox != null)
28        {
29            DrawFrameLine(rtBox);
30            Gizmos.DrawSphere(Point.position, _pointRadius);
31        }
32    }
33
34    public Rectangle CreateFromTwoPoints(Vector3 point0, Vector3 point1)
35    {
36        Rectangle rt = new Rectangle();
37        if (point0.x < point1.x)
38        {
39            rt.corner1.x = point0.x;
40            rt.corner2.x = point1.x;
41        }
42        else
43        {
44            rt.corner1.x = point1.x;
45            rt.corner2.x = point0.x;
46        }
47        if (point0.z < point1.z)
48        {
49            rt.corner1.z = point0.z;
50            rt.corner2.z = point1.z;
51        }
52        else
53        {
54            rt.corner1.z = point1.z;
55            rt.corner2.z = point0.z;
56        }
57        return rt;
58    }
59
60    protected void DrawFrameLine(Rectangle box)
61    {
62        Vector3 v0, v1, v2, v3;
63        box.GetVerts(out v0, out v1, out v2, out v3);  
64        Gizmos.DrawLine(v0, v1);
65        Gizmos.DrawLine(v1, v2);
66        Gizmos.DrawLine(v2, v3);
67        Gizmos.DrawLine(v3, v0);
68    }
69}

我们来看下效果:

不在矩形范围内:

在矩形范围内:

总结:矩形不一定是通过两个对角的点来确定.也可以通过一个中间点,然后对于中间点,偏移某个变量.也可以生成一个矩形的判断范围,只要知道四个角的点位置,就能判断.