Files
2026-07-21 08:56:10 +03:00

277 lines
9.5 KiB
C#

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<JointBlock>())
{
OnJointAdded(arg0);
}
else
{
OnBlockAdded(arg0);
}
}
public void DisconnectAllSockets(Block arg0)
{
SocketPoint[] socketPoints = arg0.GetComponentsInChildren<SocketPoint>();
if (socketPoints.Length == 0) return;
List<GameObject> attachedObjects = new List<GameObject>();
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<SocketPoint>();
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<JointBlock>())
{
OnJointRemoved(arg0);
}
else
{
OnBlockRemoved(arg0);
}
}
private void OnAdd(Block arg0)
{
if (arg0.gameObject.GetComponent<JointBlock>())
{
OnJointAdded(arg0);
}
else
{
OnBlockAdded(arg0);
}
}
private void OnBlockRemoved(Block arg0)
{
SocketPoint[] socketPoints = arg0.GetComponentsInChildren<SocketPoint>();
if (socketPoints.Length == 0)
return;
List<GameObject> attachedObjects = new List<GameObject>();
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<SocketPoint>();
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<SocketPoint>();
if (socketPoints.Length == 0)
return;
List<GameObject> attachedObjects = new List<GameObject>();
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<SocketPoint>();
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<SocketPoint>();
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<JointBlock>();
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<SocketPoint>();
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<JointBlock>();
if (joint != null && !joint.IsPlaced())
{
List<SocketPoint> 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<SocketPoint>();
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;
}
}