Files
ui/Assets/ModuleSpawner.cs
2026-01-07 23:54:53 -05:00

254 lines
9.0 KiB
C#

using System.Collections.Generic;
using System.IO;
using UnityEngine;
public class ModuleSpawner : MonoBehaviour
{
public GameObject batteryModulePrefab;
public GameObject hubModulePrefab;
public GameObject dcMotorModulePrefab;
public GameObject servoBendModulePrefab;
public GameObject servoStraightModulePrefab;
public GameObject GetPrefabForType(ModuleType type)
{
// Debug.Log($"In spawner with type: {type}.");
switch (type)
{
case ModuleType.BATTERY:
return batteryModulePrefab;
case ModuleType.SPLITTER:
return hubModulePrefab;
case ModuleType.DC_MOTOR:
return dcMotorModulePrefab;
case ModuleType.SERVO_1:
return servoBendModulePrefab;
case ModuleType.SERVO_2:
return servoStraightModulePrefab;
default:
Debug.LogError("Unknown module type: " + type);
return null;
}
}
private void Start()
{
// SpawnDCUnderServo(0); // Default orientation
// SpawnDCUnderServo(90); // Rotate DC 90° clockwise around the socket
// SpawnDCUnderServo(180); // Flip DC around the socket
// SpawnDCUnderServo(270); // Rotate DC 270 counter-clockwise around the socket
// SpawnServoServoDCChain();
// GameObject hubInstance = Instantiate(hubModulePrefab, Vector3.zero, Quaternion.identity);
// GameObject hubInstance1 = Instantiate(hubModulePrefab, Vector3.zero, Quaternion.identity);
// GameObject hubInstance2 = Instantiate(hubModulePrefab, Vector3.zero, Quaternion.identity);
// GameObject hubInstance3 = Instantiate(hubModulePrefab, Vector3.zero, Quaternion.identity);
// GameObject servo1 = Instantiate(servoBendModulePrefab, Vector3.right * 2, Quaternion.identity);
// GameObject servo2 = Instantiate(servoBendModulePrefab, Vector3.right * 4, Quaternion.identity);
// GameObject servo3 = Instantiate(servoBendModulePrefab, Vector3.right * 2, Quaternion.identity);
// GameObject servo4 = Instantiate(servoBendModulePrefab, Vector3.right * 4, Quaternion.identity);
// GameObject battery1 = Instantiate(batteryModulePrefab, Vector3.right * 6, Quaternion.identity);
// ConnectModules(
// hubInstance,
// "FemaleSocket",
// servo1,
// "ArmSocket",
// new Vector3(2, 0, 0),
// 0f
// );
// ConnectModules(
// hubInstance1,
// "FemaleSocket",
// servo2,
// "ArmSocket",
// new Vector3(2, 0, 0),
// 90f
// );
// ConnectModules(
// hubInstance2,
// "FemaleSocket",
// servo3,
// "ArmSocket",
// new Vector3(2, 0, 0),
// 180f
// );
// ConnectModules(
// hubInstance3,
// "FemaleSocket",
// servo4,
// "ArmSocket",
// new Vector3(2, 0, 0),
// 270f
// );
}
// private void SpawnBatteryModule()
// {
// Instantiate(batteryModulePrefab, new Vector3(0, 0, 0), Quaternion.identity);
// }
// private void SpawnHubModule()
// {
// Instantiate(hubModulePrefab, new Vector3(1.5f, 0, 0), Quaternion.identity);
// }
// private void SpawnDCMotorModule()
// {
// Instantiate(dcMotorModulePrefab, new Vector3(3.0f, 0, 0), Quaternion.identity);
// }
// private void SpawnServoBendModule()
// {
// Instantiate(servoBendModulePrefab, new Vector3(4.5f, 0, 0), Quaternion.identity);
// }
public void ConnectModules(
GameObject parentPrefab,
string parentSocketPath,
GameObject childPrefab,
string childSocketPath,
Vector3 spawnPosition,
float twistDegrees = 0f
)
{
// Spawn and scale both
// GameObject objA = Instantiate(parentPrefab, spawnPosition, Quaternion.identity);
// GameObject objB = Instantiate(childPrefab);
// parentPrefab.transform.localScale = new Vector3(20f, 20f, 20f);
// childPrefab.transform.localScale = new Vector3(20f, 20f, 20f);
// Locate sockets
Transform socketA = FindSocketSmartPath(parentPrefab, parentSocketPath);
Transform socketB = FindSocketSmartPath(childPrefab, childSocketPath);
if (socketA == null || socketB == null)
{
Debug.LogError("One or both sockets not found.");
Destroy(parentPrefab);
Destroy(childPrefab);
return;
}
// Check if either socket is a Servo ArmSocket
if (IsArmSocket(socketA.name) ^ IsArmSocket(socketB.name))
{
ConnectWithServoArm(parentPrefab, socketA, childPrefab, socketB, twistDegrees);
return;
}
// Normal case (no servo arm involved)
// bool aIsFemale = IsFemaleSocket(socketA.name);
// Transform parentSocket = aIsFemale ? socketA : socketB;
// Transform childSocket = aIsFemale ? socketB : socketA;
// GameObject parentObj = aIsFemale ? parentPrefab : childPrefab;
// GameObject childObj = aIsFemale ? childPrefab : parentPrefab;
bool aIsMale = IsMaleSocket(socketA.name);
Transform parentSocket = aIsMale ? socketA : socketB;
Transform childSocket = aIsMale ? socketB : socketA;
GameObject parentObj = aIsMale ? parentPrefab : childPrefab;
GameObject childObj = aIsMale ? childPrefab : parentPrefab;
Quaternion alignRotation = parentSocket.rotation * Quaternion.Inverse(childSocket.rotation);
childObj.transform.rotation = alignRotation * childObj.transform.rotation;
Vector3 posOffset = parentSocket.position - childSocket.position;
childObj.transform.position += posOffset;
if (twistDegrees != 0f)
{
childObj.transform.RotateAround(parentSocket.position, parentSocket.right, twistDegrees);
}
childObj.transform.SetParent(parentSocket.parent, worldPositionStays: true);
childObj.transform.localScale = Vector3.one;
}
private bool IsMaleSocket(string socketName)
{
return socketName.Contains("ArmSocket") || socketName.Contains("MaleSocket");
}
private void ConnectWithServoArm(
GameObject objA, Transform socketA,
GameObject objB, Transform socketB,
float twistDegrees
)
{
bool aIsArm = IsArmSocket(socketA.name);
GameObject servoObj = aIsArm ? objA : objB;
GameObject childObj = aIsArm ? objB : objA;
Transform armSocket = aIsArm ? socketA : socketB;
Transform childSocket = aIsArm ? socketB : socketA;
Quaternion alignRotation = armSocket.rotation * Quaternion.Inverse(childSocket.rotation);
childObj.transform.rotation = alignRotation * childObj.transform.rotation;
Vector3 posOffset = armSocket.position - childSocket.position;
childObj.transform.position += posOffset;
if (twistDegrees != 0f)
{
childObj.transform.RotateAround(armSocket.position, armSocket.right, twistDegrees);
}
Transform armPivot = servoObj.transform.Find("ArmPivot");
if (armPivot == null)
{
Debug.LogWarning("ArmPivot not found on servo. Falling back to default parent.");
armPivot = armSocket.parent;
}
childObj.transform.SetParent(armPivot, worldPositionStays: true);
childObj.transform.localScale = Vector3.one;
}
// private bool IsFemaleSocket(string socketName)
// {
// return socketName.Contains("BodySocket") || socketName.Contains("FemaleSocket");
// }
private Transform FindSocketSmartPath(GameObject module, string socketName)
{
// Try direct child first (for hub, battery, etc.)
// Debug.LogError("inside findSocketSmartPath for" + socketName + " " + module.name);
Transform direct = module.transform.Find(socketName);
if (direct != null) return direct;
// Debug.LogError("huh?");
// Lookup known paths based on socket name
switch (socketName)
{
case "BodySocket":
return module.transform.Find("servo_module_body_unity/BodySocket");
case "ArmSocket":
// Only Servo uses this
return module.transform.Find("ArmPivot/ArmSocket");
case "MaleSocket":
case "FemaleSocket":
return module.transform.Find(socketName);
case "MaleSocket1":
case "MaleSocket2":
case "MaleSocket3":
// Hub
return module.transform.Find(socketName);
default:
Debug.LogError($"Unknown socket name '{socketName}'");
return null;
}
}
private bool IsArmSocket(string socketName)
{
return socketName == "ArmSocket";
}
}