Unity 攻击范围检测并绘制检测区域

一、圆形检测

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);
    }

}

效果图:

二、矩形检测

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);
    }
}

效果图:

三、扇形攻击检测

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;
    }
}

效果图:

扫描二维码关注公众号,回复: 5267685 查看本文章

猜你喜欢

转载自blog.csdn.net/qq_38721111/article/details/86742317