using System.Collections; using System.Collections.Generic; using UnityEngine; public class SocketPoint : MonoBehaviour, ISocket { [Header("Socket Configuration")] [SerializeField] private SocketType socketType = SocketType.Regular; [SerializeField] private float socketRadius = 0.1f; // Hole/pin radius [SerializeField] private Vector3 socketNormal = Vector3.forward; // Which way socket faces [Header("Compatibility")] [SerializeField] private List acceptableTypes = new List(); [SerializeField] private float radiusTolerance = 0.05f; [Header("Visual")] [SerializeField] private GameObject visualIndicator; [SerializeField] private Color defaultColor = Color.white; [SerializeField] private Color activeColor = Color.yellow; [SerializeField] private Color compatibleColor = Color.green; [SerializeField] private Color incompatibleColor = Color.red; [SerializeField] private bool canHoldJoint = false; private GameObject occupyingObject; private bool isOccupied = false; private GameObject holdedJoint; private bool isJointOccupied = false; private bool CanAccept(ISocket otherSocket) { // Check type compatibility if (acceptableTypes.Count > 0 && !acceptableTypes.Contains(otherSocket.GetSocketType()) || isOccupied) return false; // Check radius compatibility (hole must be bigger or equal to pin) float radiusDiff = socketRadius - otherSocket.GetSocketRadius(); return radiusDiff >= -radiusTolerance && radiusDiff <= radiusTolerance; } public bool CanAccept(ISocket otherSocket, bool isJoint = false) { if (!isJoint) return CanAccept(otherSocket); // Check type compatibility if (acceptableTypes.Count > 0 && !acceptableTypes.Contains(otherSocket.GetSocketType()) || isJointOccupied || !canHoldJoint) return false; // Check radius compatibility (hole must be bigger or equal to pin) float radiusDiff = socketRadius - otherSocket.GetSocketRadius(); return radiusDiff >= -radiusTolerance && radiusDiff <= radiusTolerance; } public Vector3 GetNormal() { return transform.TransformDirection(socketNormal); } public void Highlight(HighlightState state) { if (visualIndicator == null) return; Renderer renderer = visualIndicator.GetComponent(); if (renderer == null) return; switch (state) { case HighlightState.Default: renderer.material.color = defaultColor; visualIndicator.SetActive(false); break; case HighlightState.Active: renderer.material.color = activeColor; visualIndicator.SetActive(true); break; case HighlightState.Compatible: renderer.material.color = compatibleColor; visualIndicator.SetActive(true); break; case HighlightState.Incompatible: renderer.material.color = incompatibleColor; visualIndicator.SetActive(true); break; } } // ISocket implementation public Transform GetTransform() => transform; public SocketType GetSocketType() => socketType; public float GetSocketRadius() => socketRadius; public void SetSocketRadius(float radius) => socketRadius = radius; public bool IsOccupied() => isOccupied; public bool IsJointOccupied() => isJointOccupied; public GameObject GetOccupyingObject() => occupyingObject; public GameObject GetJointObject() => holdedJoint; public void SetOccupied(GameObject obj) { occupyingObject = obj; isOccupied = true; } public void SetJointOccupied(GameObject jointObject) { holdedJoint = jointObject; isJointOccupied = true; } public void ReleaseJoint() { holdedJoint = null; isJointOccupied = false; } public void Release() { occupyingObject = null; isOccupied = false; } } public enum HighlightState { Default, Active, Compatible, Incompatible }