using System.Collections; using System.Collections.Generic; using System.Net.Sockets; using UnityEngine; public class SocketManagerChecker : MonoBehaviour { private Environment environment; private GhostManagerV2 ghostManager; private RayInteractor rayInteractor; private JointPlacementHandler jointPlacementHandler; [SerializeField] private float socketTolerance = 0.5f; private void Start() { environment = Environment.getInstance(); ghostManager = GhostManagerV2.getInstance(); rayInteractor = RayInteractor.getInstance(); jointPlacementHandler = JointPlacementHandler.getInstance(); environment.onBlockAddedEvent.AddListener(OnAdd); environment.onBlockRemovedEvent.AddListener(OnRemove); environment.onBlockMovedEvt.AddListener(OnMove); } private void OnMove(Block arg0, Vector3 oldPos, Quaternion oldRot) { // Re-evaluate connections after moving if (arg0.gameObject.GetComponent()) { OnJointAdded(arg0); } else { OnBlockAdded(arg0); } } public void DisconnectAllSockets(Block arg0) { SocketPoint[] socketPoints = arg0.GetComponentsInChildren(); if (socketPoints.Length == 0) return; List attachedObjects = new List(); foreach (SocketPoint socketPoint in socketPoints) { GameObject attachedObject = socketPoint.GetOccupyingObject(); if (attachedObject != null && !attachedObjects.Contains(attachedObject)) { attachedObjects.Add(attachedObject); } // Also check for joint objects GameObject jointObject = socketPoint.GetJointObject(); if (jointObject != null && !attachedObjects.Contains(jointObject)) { attachedObjects.Add(jointObject); } } foreach (GameObject attachedObject in attachedObjects) { SocketPoint[] attachedObjectSocketPoints = attachedObject.GetComponentsInChildren(); foreach (SocketPoint attachedObjectSocketPoint in attachedObjectSocketPoints) { if (attachedObjectSocketPoint.GetOccupyingObject() == arg0.gameObject) { attachedObjectSocketPoint.Release(); } if (attachedObjectSocketPoint.GetJointObject() == arg0.gameObject) { attachedObjectSocketPoint.ReleaseJoint(); } } } // Release our own sockets foreach (SocketPoint socketPoint in socketPoints) { socketPoint.Release(); socketPoint.ReleaseJoint(); } } private void OnRemove(Block arg0) { if (arg0.gameObject.GetComponent()) { OnJointRemoved(arg0); } else { OnBlockRemoved(arg0); } } private void OnAdd(Block arg0) { if (arg0.gameObject.GetComponent()) { OnJointAdded(arg0); } else { OnBlockAdded(arg0); } } private void OnBlockRemoved(Block arg0) { SocketPoint[] socketPoints = arg0.GetComponentsInChildren(); if (socketPoints.Length == 0) return; List attachedObjects = new List(); foreach (SocketPoint socketPoint in socketPoints) { GameObject attachechedObject = socketPoint.GetOccupyingObject(); if (attachechedObject != null) { if (!attachedObjects.Contains(attachechedObject)) attachedObjects.Add(attachechedObject); } } // free all the sockets attached to the current block foreach (GameObject attachedObject in attachedObjects) { SocketPoint[] attachedObjectSocketPoints = attachedObject.GetComponentsInChildren(); if (attachedObjectSocketPoints.Length == 0) continue; foreach (SocketPoint attachedObjectSocketPoint in attachedObjectSocketPoints) { if (attachedObjectSocketPoint.GetOccupyingObject() == arg0.gameObject) { attachedObjectSocketPoint.Release(); } } } environment.completeDestroyBlock(arg0); } private void OnJointRemoved(Block arg0) { SocketPoint[] socketPoints = arg0.GetComponentsInChildren(); if (socketPoints.Length == 0) return; List attachedObjects = new List(); foreach (SocketPoint socketPoint in socketPoints) { GameObject attachechedObject = socketPoint.GetOccupyingObject(); if (attachechedObject != null) { if (!attachedObjects.Contains(attachechedObject)) attachedObjects.Add(attachechedObject); } } // free all the sockets attached to the current block foreach (GameObject attachedObject in attachedObjects) { SocketPoint[] attachedObjectSocketPoints = attachedObject.GetComponentsInChildren(); if (attachedObjectSocketPoints.Length == 0) continue; foreach (SocketPoint attachedObjectSocketPoint in attachedObjectSocketPoints) { if (attachedObjectSocketPoint.GetJointObject() == arg0.gameObject) { attachedObjectSocketPoint.ReleaseJoint(); } } } environment.completeDestroyBlock(arg0); } private void OnBlockAdded(Block arg0) { SocketPoint[] socketPoints = arg0.transform.GetComponentsInChildren(); foreach (SocketPoint socketPoint in socketPoints) { SocketPoint closestSocket = getClosestSocketBy(socketPoint, socketTolerance); if (closestSocket != null) { GameObject closestSocketParent = closestSocket.transform.parent.gameObject; // check if the Block is JointBlock JointBlock jointBlock = arg0.GetComponent(); if (jointBlock != null) { GameObject occupyingObject = closestSocket.GetJointObject(); if (occupyingObject == null) { socketPoint.SetJointOccupied(closestSocketParent); closestSocket.SetOccupied(arg0.gameObject); jointBlock.CreatePhysicsJoint(arg0.gameObject, closestSocket); } } else { GameObject occupyingObject = closestSocket.GetOccupyingObject(); if (occupyingObject == null) { closestSocket.SetOccupied(arg0.gameObject); socketPoint.SetOccupied(closestSocketParent); } } } } } private void OnJointAdded(Block arg0) { SocketPoint[] socketPoints = arg0.transform.GetComponentsInChildren(); foreach (SocketPoint socketPoint in socketPoints) { SocketPoint closestSocket = getClosestSocketBy(socketPoint, socketTolerance); if (closestSocket != null) { GameObject closestSocketParent = closestSocket.transform.parent.gameObject; GameObject occupyingObject = closestSocket.GetJointObject(); if (occupyingObject == null) { closestSocket.SetJointOccupied(arg0.gameObject); socketPoint.SetOccupied(closestSocketParent); } } } // init Joint JointBlock joint = arg0.GetComponent(); if (joint != null && !joint.IsPlaced()) { List sockets = jointPlacementHandler.FindTargetSocketsForJoint( joint, rayInteractor.GetHitPosition()); joint.TryPlaceJoint(sockets); } } private SocketPoint getClosestSocketBy(SocketPoint socketPoint, float tol) { Collider[] colliders = Physics.OverlapSphere(socketPoint.transform.position, tol, Physics.AllLayers, QueryTriggerInteraction.Collide); SocketPoint closestSocket = null; float closestDistance = Mathf.Infinity; foreach (Collider collider in colliders) { SocketPoint otherSocketPoint = collider.GetComponent(); if (otherSocketPoint != null && otherSocketPoint != socketPoint) { if (collider.transform.parent == socketPoint.transform.parent || ghostManager.isGhost(collider.transform.parent.gameObject) || Vector3.Dot(socketPoint.GetNormal(), otherSocketPoint.GetNormal()) > 0.9f) { continue; } float distance = Vector3.Distance(socketPoint.transform.position, otherSocketPoint.transform.position); if (distance < closestDistance) { closestDistance = distance; closestSocket = otherSocketPoint; } } } if (closestDistance <= tol) return closestSocket; else return null; } }