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

 更新时间:2020年6月25日 10:34  点击:2163

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

效果图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持猪先飞。

[!--infotagslink--]

相关文章

  • Unity时间戳的使用方法

    这篇文章主要为大家详细介绍了Unity时间戳的使用方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity中 ShaderGraph 实现旋涡传送门效果入门级教程(推荐)

    通过Twirl 旋转节点对Gradient Noise 梯度噪声节点进行操作,就可得到一个旋转的旋涡效果。具体实现代码跟随小编一起通过本文学习下吧...2021-07-11
  • Python Pygame中精灵和碰撞检测详解

    对于游戏中出现的每一样东西,比如砖块箱子水管地面,还有人物都可以看成是一个独立的物体,所以每个物体类都继承了pygame的精灵类pg.sprite.Sprite,这篇文章主要给大家介绍了关于Python Pygame中精灵和碰撞检测的相关资料,需要的朋友可以参考下...2021-10-05
  • 如何检测JavaScript中的死循环示例详解

    这篇文章主要给大家介绍了关于如何检测JavaScript中死循环的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-31
  • Unity延时执行的多种方法小结

    本文主要介绍了4种延时执行的方法,主要包括Update计时器,Invoke,协程,DoTween,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-07-07
  • 一篇文章带你了解kali局域网攻击

    这篇文章主要给大家介绍了kali的局域网攻击,小编觉得这篇文章还是不错的,使用起来也是非常方便的,需要的朋友可以参考下...2021-08-20
  • Unity shader实现遮罩效果

    这篇文章主要为大家详细介绍了Unity shader实现遮罩效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • php预防XSS攻击的一些方法整理

    现在有很多php开发框架都提供关于防XSS攻击的过滤方法,下面和大家分享一个预防XSS攻击和ajax跨域攻击的函数,摘自某开发框架,相比于仅仅使用内置函数应该还是够强了的吧...2016-11-25
  • python基于opencv检测程序运行效率

    这篇文章主要介绍了python基于opencv检测程序运行效率,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-09
  • unity 如何判断鼠标是否在哪个UI上(两种方法)

    这篇文章主要介绍了unity 判断鼠标是否在哪个UI上的两种实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Unity实现换装系统

    这篇文章主要为大家详细介绍了Unity实现换装系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-04-11
  • iOS WKWebview 白屏检测实现的示例

    这篇文章主要介绍了iOS WKWebview 白屏检测实现的示例,帮助大家更好的进行ios开发,感兴趣的朋友可以了解下...2020-10-20
  • 利用unity代码C#封装为dll的步骤分享

    这篇文章主要给大家介绍了关于利用unity代码C#封装为dll的相关资料,文中通过图文将实现的方法介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • Unity Shader实现径向模糊效果

    这篇文章主要为大家详细介绍了Unity Shader实现径向模糊效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-08-09
  • unity 实现摄像机绕某点旋转一周

    这篇文章主要介绍了unity 实现摄像机绕某点旋转一周,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • Unity实现截图功能

    这篇文章主要为大家详细介绍了Unity实现截图功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity中EventTrigger的几种使用操作

    这篇文章主要介绍了Unity中EventTrigger的几种使用操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Unity Shader实现2D水流效果

    这篇文章主要为大家详细介绍了Unity Shader实现2D水流效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25
  • Unity 按钮添加OnClick事件操作

    这篇文章主要介绍了Unity 按钮添加OnClick事件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-10
  • Unity使用EzySlice实现模型多边形顺序切割

    这篇文章主要为大家详细介绍了Unity使用EzySlice实现模型多边形顺序切割,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-11-03