OverlapBox的绘制问题
我们发现Gizmos没有直接绘制OverlapBox的API,所以只能借助DrawLine来间接绘制OverlapBox,所以首先我们需要计算出Box四个顶点的坐标公式。
转换为如下问题:
已知有一个矩形ABCD,A为矩形的左上顶点,C为矩形的右下顶点,宽为w,高为h,矩形中心点O坐标为(a,b),∠α是OA与X轴负方向的夹角,矩形有一个外接圆,现使得矩形按中心进行顺时针或逆时针旋转θ角度,规定-π <= θ <= π,求旋转过后矩形四个顶点A1,B1,C1,D1的坐标分别是多少?
求解过程如下:
代码示例(C#)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BoxTrigger : MonoBehaviour
{
[Header("必要组件")]
[Tooltip("触发器检测层")]
[SerializeField] private LayerMask cTriggerLayer;
public LayerMask triggerLayer { get => cTriggerLayer; set => cTriggerLayer = value; }
[Tooltip("触发器检测区域的中心坐标组件")]
[SerializeField] private Transform cTriggerArea;
public Transform triggerArea { get => cTriggerArea; set => cTriggerArea = value; }
[Header("必要属性")]
[Tooltip("触发器的宽度和高度")]
[SerializeField] private Vector2 mSize;
[Tooltip("触发器的角度")]
[Range(-180f, 180f)]
[SerializeField] private float mAngle;
[Tooltip("触发器绘制颜色")]
[SerializeField] private DrawColor mColor;
public Vector2 center { get => cTriggerArea.position; }
public Vector2 size { get => mSize; set => mSize = value; }
public float angle { get => mAngle; set { if (value >= -180f && value <= 180f) mAngle = value; } }
//Trigger_check用于检测主角是否进入触发区域
private bool trigger_check { get; set; }
private Vector2 mLU;
private Vector2 mRU;
private Vector2 mRD;
private Vector2 mLD;
private Color currentColor;
private float mSin;
private float mCos;
private float mWidth;
private float mHeight;
private const float mC = 1f / 2;
void Start()
{
if (!cTriggerArea) cTriggerArea = transform;
}
void Update()
{
}
//触发检测
public bool TriggerCheck()
{
//检测是否进入了触发区域
if (!Physics2D.OverlapBox(center, mSize, mAngle, cTriggerLayer))
trigger_check = false;
else
trigger_check = true;
return trigger_check;
}
//角度转换为弧度
private void AngleConversion()
{
float v_angle = mAngle * Mathf.PI / 180;
mSin = Mathf.Sin(v_angle);
mCos = Mathf.Cos(v_angle);
}
//坐标更新
private void UpdatePosition()
{
mWidth = mSize.x;
mHeight = mSize.y;
float x_Lu = (-mC * (mWidth * mCos + mHeight * mSin)) + center.x;
float y_Lu = (mC * (mHeight * mCos - mWidth * mSin)) + center.y;
float x_Ru = (mC * (mWidth * mCos - mHeight * mSin)) + center.x;
float y_Ru = (mC * (mWidth * mSin + mHeight * mCos)) + center.y;
float x_Rd = (mC * (mWidth * mCos + mHeight * mSin)) + center.x;
float y_Rd = (mC * (mWidth * mSin - mHeight * mCos)) + center.y;
float x_Ld = (mC * (mHeight * mSin - mWidth * mCos)) + center.x;
float y_Ld = (-mC * (mHeight * mCos + mWidth * mSin)) + center.y;
mLU = new Vector2(x_Lu, y_Lu);
mRU = new Vector2(x_Ru, y_Ru);
mRD = new Vector2(x_Rd, y_Rd);
mLD = new Vector2(x_Ld, y_Ld);
}
//颜色替换
private void UpdateColor()
{
switch (mColor)
{
case DrawColor.Red:
currentColor = Color.red;
break;
case DrawColor.Blue:
currentColor = Color.blue;
break;
case DrawColor.Green:
currentColor = Color.green;
break;
case DrawColor.White:
currentColor = Color.white;
break;
case DrawColor.Yellow:
currentColor = Color.yellow;
break;
case DrawColor.Cyan:
currentColor = Color.cyan;
break;
case DrawColor.Gray:
currentColor = Color.gray;
break;
case DrawColor.Grey:
currentColor = Color.grey;
break;
case DrawColor.Magenta:
currentColor = Color.magenta;
break;
default:
currentColor = Color.red;
break;
}
}
//Gizmos绘制
private void OnDrawGizmos()
{
AngleConversion();
UpdatePosition();
UpdateColor();
Gizmos.color = currentColor;
Gizmos.DrawLine(mLU, mRU);
Gizmos.DrawLine(mRU, mRD);
Gizmos.DrawLine(mRD, mLD);
Gizmos.DrawLine(mLD, mLU);
}
}
如果这篇文章对你有帮助,请给作者点个赞吧!