104 lines
4.0 KiB
C#
104 lines
4.0 KiB
C#
using UnityEngine;
|
|
|
|
namespace Ashwild.Building
|
|
{
|
|
/// <summary>
|
|
/// Connection category of a snap socket — two sockets link only when their categories match.
|
|
/// Authored so that connectable sockets share a value (e.g. a floor's edge and a wall's foot
|
|
/// are both Floor, so a wall snaps onto a floor edge; walls meet side-to-side as Wall).
|
|
/// </summary>
|
|
public enum SnapCategory
|
|
{
|
|
Floor,
|
|
Wall,
|
|
Roof,
|
|
Pillar,
|
|
Custom
|
|
}
|
|
|
|
/// <summary>
|
|
/// One connection socket on a buildable, placed as a child transform at an edge/corner. Its
|
|
/// world position is where a matching socket clicks into place; its category decides what may
|
|
/// connect. Built pieces carry an enabled trigger collider on the snap layer so the placement
|
|
/// controller finds them by overlap; the ghost's own snap colliders are disabled with the rest
|
|
/// of the ghost, so the ghost never snaps to itself.
|
|
///
|
|
/// Once another piece connects here the socket is marked occupied — the placement snapping skips
|
|
/// occupied sockets (so two pieces never stack on the same connection) and its gizmo turns red
|
|
/// in the Scene view; while free it takes the colour of its category, so a glance at a prefab
|
|
/// tells which sockets can ever link together.
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public class BuildSnapPoint : MonoBehaviour
|
|
{
|
|
#region Serialized Fields
|
|
|
|
[Tooltip("What may connect here — a socket links only to another of the same category.")]
|
|
[SerializeField] private SnapCategory category;
|
|
|
|
#endregion
|
|
|
|
#region State
|
|
|
|
private bool occupied;
|
|
|
|
#endregion
|
|
|
|
#region Public API
|
|
|
|
public SnapCategory Category => category;
|
|
|
|
/// <summary>
|
|
/// Whether another piece is already connected to this socket.
|
|
/// </summary>
|
|
public bool IsOccupied => occupied;
|
|
|
|
/// <summary>
|
|
/// Flags the socket as taken (or freed) — set when a piece connects/disconnects here.
|
|
/// </summary>
|
|
public void SetOccupied(bool value) => occupied = value;
|
|
|
|
#endregion
|
|
|
|
#region Gizmos
|
|
|
|
private static readonly Color OccupiedColor = new Color(1f, 0.3f, 0.3f, 0.9f);
|
|
private static readonly Color FloorColor = new Color(0.3f, 0.8f, 1f, 0.9f);
|
|
private static readonly Color WallColor = new Color(0.4f, 1f, 0.5f, 0.9f);
|
|
private static readonly Color RoofColor = new Color(1f, 0.75f, 0.25f, 0.9f);
|
|
private static readonly Color PillarColor = new Color(0.8f, 0.5f, 1f, 0.9f);
|
|
private static readonly Color CustomColor = new Color(1f, 1f, 1f, 0.9f);
|
|
|
|
/// <summary>
|
|
/// Draws the socket in the editor: a sphere plus a ray along its forward (Z) axis — the
|
|
/// direction the connecting piece attaches. Two sockets link only when their forwards face
|
|
/// each other, so orient each empty's arrow outward toward where the neighbour should sit.
|
|
/// </summary>
|
|
private void OnDrawGizmos()
|
|
{
|
|
Gizmos.color = occupied ? OccupiedColor : GetCategoryColor(category);
|
|
Gizmos.DrawWireSphere(transform.position, 0.12f);
|
|
Gizmos.DrawRay(transform.position, transform.forward * 0.35f);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Maps a connection category to its Scene-view colour. Sockets that can link share a
|
|
/// category, so same-coloured gizmos are exactly the ones that may ever snap together —
|
|
/// mismatched colours on two pieces mean they will never connect.
|
|
/// </summary>
|
|
private static Color GetCategoryColor(SnapCategory value)
|
|
{
|
|
switch (value)
|
|
{
|
|
case SnapCategory.Floor: return FloorColor;
|
|
case SnapCategory.Wall: return WallColor;
|
|
case SnapCategory.Roof: return RoofColor;
|
|
case SnapCategory.Pillar: return PillarColor;
|
|
default: return CustomColor;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|