using System; using System.Collections.Generic; using Sirenix.OdinInspector; using UnityEngine; using VOID.Generic.Dict; namespace VOID.Generic.World { public class Area : MonoBehaviour { #region GIZMOS private void OnDrawGizmos() { var defaultColor = Gizmos.color; var forward = transform.forward; var right = transform.right; var back = -forward; var left = -right; if (forwardConnection.type != AreaConnectionType.Inner) { GizmosDrawBorder(left, forward, right, forwardConnection); GizmosDrawPassage(left, forward, right, forwardConnection); } if (rightConnection.type != AreaConnectionType.Inner) { GizmosDrawBorder(forward, right, back, rightConnection); GizmosDrawPassage(forward, right, back, rightConnection); } if (backConnection.type != AreaConnectionType.Inner) { GizmosDrawBorder(right, back, left, backConnection); GizmosDrawPassage(right, back, left, backConnection); } if (leftConnection.type != AreaConnectionType.Inner) { GizmosDrawBorder(back, left, forward, leftConnection); GizmosDrawPassage(back, left, forward, leftConnection); } Gizmos.color = defaultColor; } private void GizmosDrawBorder(Vector3 left, Vector3 forward, Vector3 right, AreaConnection connection) { if (connection.type == AreaConnectionType.Inner) return; var areaPos = transform.position; var floor = Vector3.up * HeightPerFloor * connection.floor; Gizmos.color = Color.red; Gizmos.DrawLine( areaPos + floor + forward * Size / 2 + left * Size / 2, areaPos + floor + forward * Size / 2 + right * Size / 2 ); } private void GizmosDrawPassage(Vector3 left, Vector3 forward, Vector3 right, AreaConnection connection) { float passageWidth; switch (connection.type) { case AreaConnectionType.Tunnel: passageWidth = 5f; break; case AreaConnectionType.Whole: passageWidth = Size - 1f; break; case AreaConnectionType.None: case AreaConnectionType.Inner: default: return; } var areaPos = transform.position; var floor = Vector3.up * HeightPerFloor * connection.floor; var passageHeight = Vector3.up * 5f; Gizmos.color = Color.blue; Gizmos.DrawLineStrip(new []{ areaPos + floor + forward * Size / 2 + left * passageWidth / 2, areaPos + floor + forward * Size / 2 + right * passageWidth / 2, areaPos + floor + passageHeight + forward * Size / 2 + right * passageWidth / 2, areaPos + floor + passageHeight + forward * Size / 2 + left * passageWidth / 2 }, true); } #endregion [BoxGroup("Constant Variables")] [HorizontalGroup("Constant Variables/Row")] [ShowInInspector] [ReadOnly] [InfoBox("Constant size of single square area. Content of this area SHOULD NOT leave given bounds.")] public const float Size = 50f; [BoxGroup("Constant Variables")] [HorizontalGroup("Constant Variables/Row")] [ShowInInspector] [ReadOnly] [InfoBox("Constant height of floor. Every floor supposed to be dividable by that value.")] public const float HeightPerFloor = 3f; [BoxGroup("Complex Area")] [HorizontalGroup("Complex Area/Row")] [ReadOnly] [InfoBox(nameof(ComplexArea) + " which is current " + nameof(Area) + "'s parent. It is filled by button in " + nameof(ComplexArea))] [DontValidate] public ComplexArea complexArea; [BoxGroup("Complex Area")] [HorizontalGroup("Complex Area/Row")] [ReadOnly] [InfoBox("Position relative to the " + nameof(ComplexArea) + ". Usable only from " + nameof(ComplexArea))] public Vector2Int position = Vector2Int.zero; [InfoBox("Connections to other areas." +"\nInner connection cant be edited here, check " + nameof(ComplexArea) + "." +"\nConnection only with matching tags can be connected.")] [BoxGroup("Connections")] public AreaConnection forwardConnection = new(); [BoxGroup("Connections")] public AreaConnection rightConnection = new(); [BoxGroup("Connections")] public AreaConnection backConnection = new(); [BoxGroup("Connections")] public AreaConnection leftConnection = new(); public List GetConnections() => new() { forwardConnection, rightConnection, backConnection, leftConnection }; public AreaConnection GetConnection(Direction2D direction) => direction switch { Direction2D.Forward => forwardConnection, Direction2D.Right => rightConnection, Direction2D.Back => backConnection, Direction2D.Left => leftConnection, _ => throw new ArgumentOutOfRangeException(nameof(direction), direction, null) }; } }