1. 程式人生 > 程式設計 >Unity實現攻擊範圍檢測並繪製檢測區域

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

效果圖:

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,4,2);
 
      if (RectAttackJubge(transform,attacked,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,60,3);
      if (UmbrellaAttact(transform,attacked.transform,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,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,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.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實現攻擊範圍檢測並繪製檢測區域

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。