Unity实现攻击范围检测并绘制检测区域
作者:画个小圆儿 发布时间:2023-09-18 21:59:10
标签: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;
}
}
效果图:
来源:https://blog.csdn.net/qq_38721111/article/details/86742317
0
投稿
猜你喜欢
- 提示:java.util.zipoutputstream
- 在工作过程中,需要将一个文件夹生成压缩文件,然后提供给用户下载。所以自己写了一个压缩文件的工具类。该工具类支持单个文件和文件夹压缩。放代码:
- 一、概述本质上,这是一个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空。Optional 是 Java 实现函
- Lambda表达式的进化之路为什么要使用Lambda表达式可以简洁代码,提高代码的可读性可以避免匿名内部类定义过多导致逻辑紊乱在原先实现接口
- 本文实例为大家分享了Java从服务端下载Excel模板文件的具体实现代码,供大家参考,具体内容如下方法一 (2021年01月更新)生成exc
- 前言前面一篇我们介绍了使用 shared_preferences实现简单的键值对存储,然而我们还会面临更为复杂的本地存储。比如资讯类 App
- 最近在做上传文件的服务,简单看了网上的教程。结合实践共享出代码。由于网上的大多数没有服务端的代码,这可不行呀,没服务端怎么调试呢。Ok,先上
- 下面一段简单的代码给大家分享java 获取对象中为null的字段,具体代码如下所述:private static String[] getN
- 一、项目背景在实际工作中,会遇到业务比较集中的情况,随着时间推延,这部分业务关联的mysql表就会越来越大,十分臃肿。尽管在项目架构上做了读
- 我们知道在编程时许多操作(如更新UI)需要在主线程中完成,而且,耗时操作(如网络连接)需要放在子线程中,否则会引起ANR。所以我们常使用Ha
- 本文实例讲述了Java泛型类与泛型方法的定义。分享给大家供大家参考,具体如下:Java泛型类的定义一 点睛泛型类定义的语法如下:[访问修饰符
- 阿里终面在线编程题,写出来与大家分享一下 有一个单向链表
- 匿名类类型类可以是匿名的 - 也就是说,可以在没有 identifier 的情况下声明类。在将类名称替换为 typedef 名称时,这会很有
- 正确使用并行流,避免共享可变状态错用并行流而产生错误的首要原因,就是使用的算法改变了某些共享状态。下面是另一种实现对前n个自然数求和的方法,
- 本文实例讲述了java实现新浪微博Oauth接口发送图片和文字的方法。分享给大家供大家参考。具体如下:基于网上很多人利用新浪api开发新浪微
- springboot上传文件大小的配置我这里记录两种,一种是设置在配置文件里只有两行代码,一种是加个Bean首先第一种:applicatio
- ImageCacheconst int _kDefaultSize = 1000;const int _kDefaultSizeBytes
- 方法重载概述方法重载指同一个类中定义的多个方法之间的关系,满足下列条件的多个方法互相构成重载* 多个方法在同一个类中* 多个放方法具有相同方
- 文件上传页面<%@ page language="java" contentType="text/htm
- 我们在j2ee当中,连接数据库的时候经常会用到properties配置文件,我们原来在eclipse或者myeclipse当中会在src文件