195 lines
6.2 KiB
C#
195 lines
6.2 KiB
C#
using UnityEngine;
|
|
|
|
namespace AibisDream
|
|
{
|
|
/// <summary>
|
|
/// 矩形区域组件
|
|
/// 用于划定一个矩形区域,并判断点是否在区域内
|
|
/// </summary>
|
|
public class BoxArea : MonoBehaviour
|
|
{
|
|
[Header("Box尺寸设置")]
|
|
[SerializeField] private float width = 10f;
|
|
[SerializeField] private float height = 10f;
|
|
|
|
[Header("原点位置设置")]
|
|
[Tooltip("设置(0,0)点在Box中的位置")]
|
|
[SerializeField] private AnchorPoint anchorPoint = AnchorPoint.Center;
|
|
|
|
/// <summary>
|
|
/// Box的宽度
|
|
/// </summary>
|
|
public float Width
|
|
{
|
|
get => width;
|
|
set => width = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Box的高度
|
|
/// </summary>
|
|
public float Height
|
|
{
|
|
get => height;
|
|
set => height = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 锚点位置
|
|
/// </summary>
|
|
public AnchorPoint AnchorPoint
|
|
{
|
|
get => anchorPoint;
|
|
set => anchorPoint = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取Box的世界坐标边界
|
|
/// </summary>
|
|
public Bounds WorldBounds
|
|
{
|
|
get
|
|
{
|
|
Vector3 center = GetWorldCenter();
|
|
Vector3 size = new Vector3(width, height, 0f);
|
|
return new Bounds(center, size);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取Box的本地坐标边界
|
|
/// </summary>
|
|
public Rect LocalRect
|
|
{
|
|
get
|
|
{
|
|
Vector2 offset = GetAnchorOffset();
|
|
return new Rect(offset.x, offset.y, width, height);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 判断给定的世界坐标位置是否在Box内
|
|
/// </summary>
|
|
/// <param name="worldPosition">世界坐标位置</param>
|
|
/// <returns>如果位置在Box内返回true,否则返回false</returns>
|
|
public bool Contains(Vector3 worldPosition)
|
|
{
|
|
// 将世界坐标转换为本地坐标
|
|
Vector3 localPosition = transform.InverseTransformPoint(worldPosition);
|
|
|
|
// 获取本地坐标的矩形区域
|
|
Rect rect = LocalRect;
|
|
|
|
// 判断点是否在矩形内(只考虑X和Y轴,忽略Z轴)
|
|
return rect.Contains(new Vector2(localPosition.x, localPosition.y));
|
|
}
|
|
|
|
/// <summary>
|
|
/// 判断给定的本地坐标位置是否在Box内
|
|
/// </summary>
|
|
/// <param name="localPosition">本地坐标位置</param>
|
|
/// <returns>如果位置在Box内返回true,否则返回false</returns>
|
|
public bool ContainsLocal(Vector2 localPosition)
|
|
{
|
|
Rect rect = LocalRect;
|
|
return rect.Contains(localPosition);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取Box的世界坐标中心点
|
|
/// </summary>
|
|
private Vector3 GetWorldCenter()
|
|
{
|
|
Vector2 anchorOffset = GetAnchorOffset();
|
|
Vector3 localCenter = new Vector3(anchorOffset.x + width * 0.5f, anchorOffset.y + height * 0.5f, 0f);
|
|
return transform.TransformPoint(localCenter);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据锚点位置获取偏移量
|
|
/// </summary>
|
|
private Vector2 GetAnchorOffset()
|
|
{
|
|
return anchorPoint switch
|
|
{
|
|
AnchorPoint.BottomLeft => new Vector2(0f, 0f),
|
|
AnchorPoint.BottomCenter => new Vector2(-width * 0.5f, 0f),
|
|
AnchorPoint.BottomRight => new Vector2(-width, 0f),
|
|
AnchorPoint.CenterLeft => new Vector2(0f, -height * 0.5f),
|
|
AnchorPoint.Center => new Vector2(-width * 0.5f, -height * 0.5f),
|
|
AnchorPoint.CenterRight => new Vector2(-width, -height * 0.5f),
|
|
AnchorPoint.TopLeft => new Vector2(0f, -height),
|
|
AnchorPoint.TopCenter => new Vector2(-width * 0.5f, -height),
|
|
AnchorPoint.TopRight => new Vector2(-width, -height),
|
|
_ => new Vector2(-width * 0.5f, -height * 0.5f)
|
|
};
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
/// <summary>
|
|
/// 在Scene视图中绘制Box边界(选中时)
|
|
/// </summary>
|
|
private void OnDrawGizmos()
|
|
{
|
|
// 保存原始颜色
|
|
Color originalColor = Gizmos.color;
|
|
|
|
// 设置Box边界颜色
|
|
Gizmos.color = Color.cyan;
|
|
|
|
// 获取Box的四个角点(世界坐标)
|
|
Vector2 offset = GetAnchorOffset();
|
|
Vector3[] corners = new Vector3[4]
|
|
{
|
|
transform.TransformPoint(new Vector3(offset.x, offset.y, 0f)), // 左下角
|
|
transform.TransformPoint(new Vector3(offset.x + width, offset.y, 0f)), // 右下角
|
|
transform.TransformPoint(new Vector3(offset.x + width, offset.y + height, 0f)), // 右上角
|
|
transform.TransformPoint(new Vector3(offset.x, offset.y + height, 0f)) // 左上角
|
|
};
|
|
|
|
// 绘制Box边界线
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
int next = (i + 1) % 4;
|
|
Gizmos.DrawLine(corners[i], corners[next]);
|
|
}
|
|
|
|
// 绘制中心点标记
|
|
Gizmos.color = Color.green;
|
|
Vector3 center = GetWorldCenter();
|
|
Gizmos.DrawWireSphere(center, 0.15f);
|
|
|
|
// 恢复原始颜色
|
|
Gizmos.color = originalColor;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/// <summary>
|
|
/// 锚点位置枚举
|
|
/// 定义(0,0)点在Box中的位置
|
|
/// </summary>
|
|
public enum AnchorPoint
|
|
{
|
|
[Tooltip("左下角")]
|
|
BottomLeft,
|
|
[Tooltip("底部中心")]
|
|
BottomCenter,
|
|
[Tooltip("右下角")]
|
|
BottomRight,
|
|
[Tooltip("左侧中心")]
|
|
CenterLeft,
|
|
[Tooltip("中心")]
|
|
Center,
|
|
[Tooltip("右侧中心")]
|
|
CenterRight,
|
|
[Tooltip("左上角")]
|
|
TopLeft,
|
|
[Tooltip("顶部中心")]
|
|
TopCenter,
|
|
[Tooltip("右上角")]
|
|
TopRight
|
|
}
|
|
}
|