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

本文实例为大家分享了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;

}

}

效果图:

以上是 Unity实现攻击范围检测并绘制检测区域 的全部内容, 来源链接: utcz.com/z/311985.html

回到顶部