Unity中通过Gizmos绘制OverlapBox

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

如果这篇文章对你有帮助,请给作者点个赞吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值