using UnityEngine; using UnityEngine.Events; [RequireComponent(typeof(Collider))] public class Slot : MonoBehaviour { public ItemType requiredItemType; public bool isOccupied; [Header("Visuals")] public Material normalMaterial; public Material validPreviewMaterial; public Material invalidPreviewMaterial; public Material successMaterial; [Header("Placement")] public Transform snapPoint; public UnityEvent onItemPlaced = new UnityEvent(); private Renderer slotRenderer; private DraggableObject placedItem; private void Awake() { slotRenderer = GetComponent(); if (slotRenderer != null && normalMaterial == null) { normalMaterial = slotRenderer.sharedMaterial; } } private void Start() { ApplyMaterial(normalMaterial); } public bool CanAccept(DraggableObject item) { return item != null && !isOccupied && item.itemType == requiredItemType; } public void PlaceItem(DraggableObject item) { if (!CanAccept(item)) { ShowPreview(item); return; } isOccupied = true; placedItem = item; // SnapPoint задаёт точку фиксации предмета над плоскостью слота. Vector3 targetPosition = snapPoint != null ? snapPoint.position : transform.position + Vector3.up * 0.35f; item.LockToSlot(targetPosition); ApplyMaterial(successMaterial); onItemPlaced.Invoke(); } public void ResetSlot() { isOccupied = false; placedItem = null; ApplyMaterial(normalMaterial); } public void ShowPreview(DraggableObject item) { if (isOccupied) { ApplyMaterial(successMaterial); return; } ApplyMaterial(CanAccept(item) ? validPreviewMaterial : invalidPreviewMaterial); } public void ClearPreview() { ApplyMaterial(isOccupied ? successMaterial : normalMaterial); } private void ApplyMaterial(Material material) { if (slotRenderer != null && material != null) { slotRenderer.sharedMaterial = material; } } }