欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-02-19 15:13:10
本文实例为大家分享了unity实现攻击范围检测并绘制检测区域的具体代码,供大家参考,具体内容如下一、圆形检测using system.collections;using system.collecti...

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

效果图:

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

二、矩形检测

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

效果图:

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

三、扇形攻击检测

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实现攻击范围检测并绘制检测区域

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