using UnityEngine; namespace AibisDream { /// /// 矩形区域组件 /// 用于划定一个矩形区域,并判断点是否在区域内 /// 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; /// /// Box的宽度 /// public float Width { get => width; set => width = value; } /// /// Box的高度 /// public float Height { get => height; set => height = value; } /// /// 锚点位置 /// public AnchorPoint AnchorPoint { get => anchorPoint; set => anchorPoint = value; } /// /// 获取Box的世界坐标边界 /// public Bounds WorldBounds { get { Vector3 center = GetWorldCenter(); Vector3 size = new Vector3(width, height, 0f); return new Bounds(center, size); } } /// /// 获取Box的本地坐标边界 /// public Rect LocalRect { get { Vector2 offset = GetAnchorOffset(); return new Rect(offset.x, offset.y, width, height); } } /// /// 判断给定的世界坐标位置是否在Box内 /// /// 世界坐标位置 /// 如果位置在Box内返回true,否则返回false 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)); } /// /// 判断给定的本地坐标位置是否在Box内 /// /// 本地坐标位置 /// 如果位置在Box内返回true,否则返回false public bool ContainsLocal(Vector2 localPosition) { Rect rect = LocalRect; return rect.Contains(localPosition); } /// /// 获取Box的世界坐标中心点 /// 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); } /// /// 根据锚点位置获取偏移量 /// 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 /// /// 在Scene视图中绘制Box边界(选中时) /// 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 } /// /// 锚点位置枚举 /// 定义(0,0)点在Box中的位置 /// public enum AnchorPoint { [Tooltip("左下角")] BottomLeft, [Tooltip("底部中心")] BottomCenter, [Tooltip("右下角")] BottomRight, [Tooltip("左侧中心")] CenterLeft, [Tooltip("中心")] Center, [Tooltip("右侧中心")] CenterRight, [Tooltip("左上角")] TopLeft, [Tooltip("顶部中心")] TopCenter, [Tooltip("右上角")] TopRight } }