ND_SimulationAutomaticControl/Assets/Scripts/Line/WireDataPersistence.cs

1753 lines
65 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UIElements;
// 可序列化的连线数据
[System.Serializable]
public class SerializableWireData
{
public List<SerializableWireConnectionData> wires = new List<SerializableWireConnectionData>();
public System.DateTime lastSaveTime;
public int wireCount;
public string sceneName;
}
// 连线连接数据序列化结构
[System.Serializable]
public class SerializableWireConnectionData
{
public string startInterfaceName;
public string endInterfaceName;
public Vector3 startConnectionPointPosition;
public Vector3 endConnectionPointPosition;
public Vector3 startPoint;
public Vector3 endPoint;
public string wireName;
public System.DateTime creationTime;
// 圆柱体特定数据
public Vector3 cylinderScale;
public Vector3 cylinderPosition;
public Quaternion cylinderRotation;
public float cylinderRadius;
// 调试信息
public bool hasStartInterface;
public bool hasEndInterface;
public string debugInfo;
public string wireType;
// 新增:颜色数据
public float wireColorR = 1f;
public float wireColorG = 1f;
public float wireColorB = 1f;
public float wireColorA = 1f;
public bool hasCustomColor = false;
// 新增:连接点样式数据
public float connectionPointScale = 0.1f;
public float startPointColorR = 1f;
public float startPointColorG = 1f;
public float startPointColorB = 1f;
public float endPointColorR = 1f;
public float endPointColorG = 1f;
public float endPointColorB = 1f;
}
public class WireDataPersistence : MonoBehaviour
{
[Header("数据持久化设置")]
public bool enableAutoSave = true; // 启用自动保存
public float autoSaveInterval = 30f; // 自动保存间隔(秒)
public string saveFileName = "WireData.json"; // 保存文件名
public bool loadOnStart = true; // 启动时自动加载
public bool debugMode = true; // 调试模式
public bool saveOnWireChange = true; // 连线变化时立即保存
[Header("圆柱体连线设置")]
public Material cylinderWireMaterial; // 圆柱体连线材质
public Color defaultWireColor = Color.white; // 默认连线颜色
[Header("连接点设置")]
public Material defaultConnectionPointMaterial; // 默认连接点材质
public Color defaultStartPointColor = Color.green; // 默认起点颜色
public Color defaultEndPointColor = Color.red; // 默认终点颜色
[Header("调试工具")]
public bool enableDebugging = true; // 启用调试工具
public KeyCode manualSaveKey = KeyCode.F5; // 手动保存快捷键
public KeyCode manualLoadKey = KeyCode.F9; // 手动加载快捷键
public KeyCode debugInfoKey = KeyCode.F11; // 调试信息快捷键
// 引用连线系统
private WireDrawingSystem wireSystem;
private string saveFilePath;
private float lastSaveTime;
private bool isInitialized = false;
private int lastWireCount = 0;
void Start()
{
Initialize();
}
void Update()
{
if (!isInitialized) return;
// 处理快捷键
HandleHotkeys();
// 检查连线数量变化
if (saveOnWireChange)
{
CheckWireCountChange();
}
// 自动保存检查
if (enableAutoSave && Time.time - lastSaveTime >= autoSaveInterval)
{
SaveWireData();
lastSaveTime = Time.time;
}
}
/// <summary>
/// 处理快捷键
/// </summary>
private void HandleHotkeys()
{
if (Input.GetKeyDown(manualSaveKey))
{
Debug.Log("手动保存触发");
SaveWireData();
}
if (Input.GetKeyDown(manualLoadKey))
{
Debug.Log("手动加载触发");
LoadWireData();
}
if (Input.GetKeyDown(debugInfoKey))
{
ShowDebugInfo();
}
// 新增:堆叠系统验证快捷键
if (Input.GetKeyDown(KeyCode.F12))
{
Debug.Log("验证堆叠系统");
ValidateStackingSystem();
}
if (Input.GetKeyDown(KeyCode.F10))
{
TestStackingLimit("chudian218");
}
}
/// <summary>
/// 显示调试信息
/// </summary>
private void ShowDebugInfo()
{
Debug.Log("=== 连线数据持久化调试信息 ===");
Debug.Log($"保存文件路径: {saveFilePath}");
Debug.Log($"文件存在: {File.Exists(saveFilePath)}");
Debug.Log($"当前连线数量: {GetCurrentWireCount()}");
Debug.Log($"上次保存连线数量: {lastWireCount}");
Debug.Log($"系统初始化: {isInitialized}");
Debug.Log($"连线系统引用: {wireSystem != null}");
if (File.Exists(saveFilePath))
{
try
{
string jsonData = File.ReadAllText(saveFilePath);
SerializableWireData data = JsonUtility.FromJson<SerializableWireData>(jsonData);
Debug.Log($"保存文件中的连线数量: {data.wireCount}");
Debug.Log($"保存时间: {data.lastSaveTime}");
Debug.Log($"场景名称: {data.sceneName}");
Debug.Log($"实际保存的连线数据条数: {data.wires.Count}");
// 显示连线类型统计和颜色信息
var typeGroups = data.wires.GroupBy(w => w.wireType);
foreach (var group in typeGroups)
{
Debug.Log($"连线类型 '{group.Key}': {group.Count()} 条");
}
// 显示颜色信息
int coloredWires = data.wires.Count(w => w.hasCustomColor);
Debug.Log($"有自定义颜色的连线: {coloredWires}/{data.wires.Count}");
}
catch (System.Exception e)
{
Debug.LogError($"读取保存文件失败: {e.Message}");
}
}
}
/// <summary>
/// 检查连线数量变化
/// </summary>
private void CheckWireCountChange()
{
try
{
int currentWireCount = GetCurrentWireCount();
if (currentWireCount != lastWireCount)
{
if (debugMode) Debug.Log($"WireDataPersistence: 连线数量变化 {lastWireCount} -> {currentWireCount}, 触发保存");
SaveWireData();
lastWireCount = currentWireCount;
}
}
catch (System.Exception e)
{
Debug.LogWarning($"WireDataPersistence: 检查连线数量变化失败: {e.Message}");
}
}
/// <summary>
/// 获取当前连线数量
/// </summary>
private int GetCurrentWireCount()
{
if (wireSystem == null) return 0;
try
{
// 通过反射获取连线系统的私有字段
var allWiresField = typeof(WireDrawingSystem).GetField("allWires",
BindingFlags.NonPublic | BindingFlags.Instance);
if (allWiresField == null)
{
if (debugMode) Debug.LogError("无法找到 allWires 字段");
return 0;
}
List<GameObject> allWires = (List<GameObject>)allWiresField.GetValue(wireSystem);
return allWires?.Count ?? 0;
}
catch (System.Exception e)
{
if (debugMode) Debug.LogError($"获取连线数量失败: {e.Message}");
return 0;
}
}
/// <summary>
/// 初始化数据持久化系统
/// </summary>
public void Initialize()
{
if (isInitialized) return;
// 获取连线系统引用
wireSystem = GetComponent<WireDrawingSystem>();
if (wireSystem == null)
{
Debug.LogError("WireDataPersistence: 找不到 WireDrawingSystem 组件!");
return;
}
// 设置保存文件路径
saveFilePath = Path.Combine(Application.streamingAssetsPath, saveFileName);
if (debugMode) Debug.Log($"WireDataPersistence: 数据保存路径: {saveFilePath}");
// 启动时加载数据
if (loadOnStart)
{
// 延迟一帧加载,确保所有组件已初始化
StartCoroutine(DelayedLoad());
}
// 初始化连线计数
lastWireCount = GetCurrentWireCount();
lastSaveTime = Time.time;
isInitialized = true;
if (debugMode) Debug.Log("WireDataPersistence: 初始化完成");
}
/// <summary>
/// 延迟加载
/// </summary>
private IEnumerator DelayedLoad()
{
yield return new WaitForEndOfFrame();
LoadWireData();
}
/// <summary>
/// 保存连线数据到文件
/// </summary>
public void SaveWireData()
{
if (!isInitialized || wireSystem == null)
{
Debug.LogWarning("WireDataPersistence: 系统未初始化,无法保存数据");
return;
}
try
{
// 通过反射获取连线系统的私有字段
var allWiresField = typeof(WireDrawingSystem).GetField("allWires",
BindingFlags.NonPublic | BindingFlags.Instance);
if (allWiresField == null)
{
Debug.LogError("WireDataPersistence: 无法访问连线系统的内部数据");
return;
}
List<GameObject> allWires = (List<GameObject>)allWiresField.GetValue(wireSystem);
SerializableWireData data = new SerializableWireData();
data.lastSaveTime = System.DateTime.Now;
data.wireCount = allWires?.Count ?? 0;
data.sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
// 收集所有连线的数据
int savedCount = 0;
if (allWires != null)
{
foreach (var wire in allWires)
{
if (wire != null)
{
SerializableWireConnectionData wireData = GetWireConnectionData(wire);
if (wireData != null)
{
data.wires.Add(wireData);
savedCount++;
if (debugMode) Debug.Log($"成功保存连线数据: {wireData.wireName} (类型: {wireData.wireType}, 颜色: {wireData.hasCustomColor})");
}
else
{
if (debugMode) Debug.LogWarning($"无法获取连线数据: {wire.name}");
}
}
}
}
string jsonData = JsonUtility.ToJson(data, true);
// 确保目录存在
string directory = Path.GetDirectoryName(saveFilePath);
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
File.WriteAllText(saveFilePath, jsonData);
if (debugMode)
{
Debug.Log($"WireDataPersistence: 数据已保存: {savedCount}/{data.wireCount} 条连线");
Debug.Log($"保存文件大小: {jsonData.Length} 字符");
// 显示连线类型统计
var typeGroups = data.wires.GroupBy(w => w.wireType);
foreach (var group in typeGroups)
{
Debug.Log($"保存的连线类型 '{group.Key}': {group.Count()} 条");
}
// 显示颜色统计
int coloredWires = data.wires.Count(w => w.hasCustomColor);
Debug.Log($"保存的有颜色连线: {coloredWires}/{data.wires.Count}");
}
}
catch (System.Exception e)
{
Debug.LogError($"WireDataPersistence: 保存数据失败: {e.Message}\n{e.StackTrace}");
}
}
/// <summary>
/// 从文件加载连线数据
/// </summary>
public void LoadWireData()
{
if (!isInitialized || wireSystem == null)
{
Debug.LogWarning("WireDataPersistence: 系统未初始化,无法加载数据");
return;
}
try
{
if (!File.Exists(saveFilePath))
{
if (debugMode) Debug.Log("WireDataPersistence: 没有找到连线数据文件");
return;
}
string jsonData = File.ReadAllText(saveFilePath);
if (string.IsNullOrEmpty(jsonData))
{
Debug.LogError("WireDataPersistence: 保存文件为空");
return;
}
SerializableWireData data = JsonUtility.FromJson<SerializableWireData>(jsonData);
if (debugMode)
{
Debug.Log($"WireDataPersistence: 开始加载数据: {data.wires.Count} 条连线, 保存时间: {data.lastSaveTime}");
// 显示连线类型统计
var typeGroups = data.wires.GroupBy(w => w.wireType);
foreach (var group in typeGroups)
{
Debug.Log($"要加载的连线类型 '{group.Key}': {group.Count()} 条");
}
// 显示颜色统计
int coloredWires = data.wires.Count(w => w.hasCustomColor);
Debug.Log($"要加载的有颜色连线: {coloredWires}/{data.wires.Count}");
}
// 如果 wires 为空但 wireCount > 0说明数据有问题
if (data.wires.Count == 0 && data.wireCount > 0)
{
Debug.LogError($"数据不一致: wireCount = {data.wireCount}, 但 wires 数组为空");
return;
}
// 调用连线系统的清除方法
var clearAllMethod = typeof(WireDrawingSystem).GetMethod("ClearAll",
BindingFlags.Public | BindingFlags.Instance);
if (clearAllMethod != null)
{
clearAllMethod.Invoke(wireSystem, null);
}
else
{
Debug.LogWarning("WireDataPersistence: 无法调用 WireDrawingSystem 的 ClearAll 方法");
// 尝试手动清除
ManualClearWires();
}
// 重建连线
int reconstructedCount = 0;
foreach (var wireData in data.wires)
{
if (ReconstructWire(wireData))
{
reconstructedCount++;
}
}
if (debugMode) Debug.Log($"WireDataPersistence: 数据加载完成: {reconstructedCount}/{data.wires.Count} 条连线已恢复");
// 更新连线计数
lastWireCount = GetCurrentWireCount();
// 新增:验证堆叠系统
ValidateStackingSystem();
}
catch (System.Exception e)
{
Debug.LogError($"WireDataPersistence: 加载数据失败: {e.Message}\n{e.StackTrace}");
}
}
/// <summary>
/// 手动清除连线(备用方法)
/// </summary>
private void ManualClearWires()
{
try
{
var allWiresField = typeof(WireDrawingSystem).GetField("allWires",
BindingFlags.NonPublic | BindingFlags.Instance);
var allConnectionPointsField = typeof(WireDrawingSystem).GetField("allConnectionPoints",
BindingFlags.NonPublic | BindingFlags.Instance);
if (allWiresField != null)
{
List<GameObject> allWires = (List<GameObject>)allWiresField.GetValue(wireSystem);
if (allWires != null)
{
foreach (var wire in allWires.ToList())
{
if (wire != null) DestroyImmediate(wire);
}
allWires.Clear();
}
}
if (allConnectionPointsField != null)
{
List<GameObject> allConnectionPoints = (List<GameObject>)allConnectionPointsField.GetValue(wireSystem);
if (allConnectionPoints != null)
{
foreach (var point in allConnectionPoints.ToList())
{
if (point != null) DestroyImmediate(point);
}
allConnectionPoints.Clear();
}
}
Debug.Log("手动清除连线完成");
}
catch (System.Exception e)
{
Debug.LogError($"手动清除连线失败: {e.Message}");
}
}
/// <summary>
/// 根据保存的数据重建连线
/// </summary>
private bool ReconstructWire(SerializableWireConnectionData wireData)
{
try
{
if (debugMode) Debug.Log($"开始重建连线: {wireData.wireName} (类型: {wireData.wireType}, 颜色: {wireData.hasCustomColor})");
// 查找接口物体
GameObject startInterface = FindInterfaceByName(wireData.startInterfaceName);
GameObject endInterface = FindInterfaceByName(wireData.endInterfaceName);
// 如果接口不存在记录警告但继续重建使用null接口
if (startInterface == null && !string.IsNullOrEmpty(wireData.startInterfaceName))
{
Debug.LogWarning($"无法找到起点接口: {wireData.startInterfaceName},将创建无接口连接");
}
if (endInterface == null && !string.IsNullOrEmpty(wireData.endInterfaceName))
{
Debug.LogWarning($"无法找到终点接口: {wireData.endInterfaceName},将创建无接口连接");
}
if (debugMode)
{
Debug.Log($"起点接口: {wireData.startInterfaceName} -> {startInterface != null}");
Debug.Log($"终点接口: {wireData.endInterfaceName} -> {endInterface != null}");
}
// 根据连线类型重建
if (wireData.wireType == "CylinderWireData")
{
return ReconstructCylinderWire(wireData, startInterface, endInterface);
}
else
{
// 默认使用圆柱体连线
return ReconstructCylinderWire(wireData, startInterface, endInterface);
}
}
catch (System.Exception e)
{
Debug.LogError($"WireDataPersistence: 重建连线失败: {e.Message}\n{e.StackTrace}");
return false;
}
}
/// <summary>
/// 重建圆柱体连线 - 使用保存的圆柱体数据
/// </summary>
private bool ReconstructCylinderWire(SerializableWireConnectionData wireData, GameObject startInterface, GameObject endInterface)
{
try
{
if (debugMode) Debug.Log($"重建圆柱体连线: {wireData.wireName}");
// 创建连线对象
GameObject wireObject = new GameObject(wireData.wireName);
// 首先创建连接点,因为 CylinderWireData 可能需要引用它们
List<GameObject> connectionPoints = CreateConnectionPointsForWire(wireObject, wireData, startInterface, endInterface);
// 添加 CylinderWireData 组件
CylinderWireData cylinderData = wireObject.AddComponent<CylinderWireData>();
// 使用保存的连接点对象(如果有的话)
GameObject startConnectionPoint = connectionPoints.Find(p => p.name.Contains("Start"));
GameObject endConnectionPoint = connectionPoints.Find(p => p.name.Contains("End"));
// 创建圆柱体视觉表现 - 使用保存的圆柱体数据
CreateCylinderVisual(wireObject, wireData);
// 使用反射设置 CylinderWireData 的所有字段
SetCylinderWireDataFields(cylinderData, wireData, startInterface, endInterface);
// 特别设置连接点引用(如果 CylinderWireData 需要它们)
SetConnectionPointReferences(cylinderData, startConnectionPoint, endConnectionPoint);
// 添加到连线系统
AddWireToSystem(wireObject, wireData, startInterface, endInterface);
// 注册连接点到堆叠系统
RegisterConnectionPointsToStackSystem(wireObject, startInterface, endInterface);
if (debugMode)
{
Debug.Log($"WireDataPersistence: 成功重建圆柱体连线: {wireData.wireName}");
Debug.Log($"圆柱体缩放: {wireData.cylinderScale}, 位置: {wireData.cylinderPosition}");
Debug.Log($"连线颜色: {wireData.hasCustomColor}");
// 验证 CylinderWireData 字段是否设置正确
ValidateCylinderWireData(cylinderData);
}
return true;
}
catch (System.Exception e)
{
Debug.LogError($"重建圆柱体连线失败: {e.Message}");
return false;
}
}
/// <summary>
/// 设置连接点引用
/// </summary>
private void SetConnectionPointReferences(CylinderWireData cylinderData, GameObject startPoint, GameObject endPoint)
{
try
{
FieldInfo[] fields = typeof(CylinderWireData).GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
try
{
if (field.FieldType == typeof(GameObject))
{
if (field.Name.ToLower().Contains("start") && field.Name.ToLower().Contains("point"))
{
field.SetValue(cylinderData, startPoint);
if (debugMode) Debug.Log($"设置起点连接点引用: {startPoint?.name ?? "null"}");
}
else if (field.Name.ToLower().Contains("end") && field.Name.ToLower().Contains("point"))
{
field.SetValue(cylinderData, endPoint);
if (debugMode) Debug.Log($"设置终点连接点引用: {endPoint?.name ?? "null"}");
}
}
}
catch (System.Exception e)
{
Debug.LogWarning($"设置连接点引用 {field.Name} 失败: {e.Message}");
}
}
}
catch (System.Exception e)
{
Debug.LogError($"设置连接点引用失败: {e.Message}");
}
}
/// <summary>
/// 验证 CylinderWireData 字段设置
/// </summary>
private void ValidateCylinderWireData(CylinderWireData cylinderData)
{
try
{
FieldInfo[] fields = typeof(CylinderWireData).GetFields(BindingFlags.Public | BindingFlags.Instance);
Debug.Log("=== CylinderWireData 字段验证 ===");
foreach (FieldInfo field in fields)
{
object value = field.GetValue(cylinderData);
Debug.Log($"{field.Name}: {value ?? "null"} (类型: {field.FieldType})");
}
Debug.Log("=== 验证结束 ===");
}
catch (System.Exception e)
{
Debug.LogError($"验证 CylinderWireData 失败: {e.Message}");
}
}
/// <summary>
/// 注册连接点到堆叠系统 - 增强版
/// </summary>
private void RegisterConnectionPointsToStackSystem(GameObject wireObject, GameObject startInterface, GameObject endInterface)
{
try
{
if (wireSystem == null)
{
if (debugMode) Debug.LogWarning("WireSystem 为 null无法注册连接点到堆叠系统");
return;
}
// 获取 WireDrawingSystem 中的 interfaceStacks 字典
var interfaceStacksField = typeof(WireDrawingSystem).GetField("interfaceStacks",
BindingFlags.NonPublic | BindingFlags.Instance);
if (interfaceStacksField == null)
{
if (debugMode) Debug.LogWarning("无法找到 interfaceStacks 字段");
return;
}
var interfaceStacks = (Dictionary<string, List<GameObject>>)interfaceStacksField.GetValue(wireSystem);
// 获取 allConnectionPoints 列表
var allConnectionPointsField = typeof(WireDrawingSystem).GetField("allConnectionPoints",
BindingFlags.NonPublic | BindingFlags.Instance);
List<GameObject> allConnectionPoints = null;
if (allConnectionPointsField != null)
{
allConnectionPoints = (List<GameObject>)allConnectionPointsField.GetValue(wireSystem);
}
// 查找连线对象下的连接点并注册
int registeredCount = 0;
foreach (Transform child in wireObject.transform)
{
if (child.name.StartsWith("ConnectionPoint_Start"))
{
// 只有当起点接口存在时才注册到堆叠系统
if (startInterface != null)
{
RegisterConnectionPointWithInterface(interfaceStacks, child.gameObject, startInterface);
// 同时添加到 allConnectionPoints 列表
if (allConnectionPoints != null && !allConnectionPoints.Contains(child.gameObject))
{
allConnectionPoints.Add(child.gameObject);
}
registeredCount++;
}
else if (debugMode)
{
Debug.Log($"起点接口为 null跳过堆叠注册: {child.name}");
}
}
else if (child.name.StartsWith("ConnectionPoint_End"))
{
// 只有当终点接口存在时才注册到堆叠系统
if (endInterface != null)
{
RegisterConnectionPointWithInterface(interfaceStacks, child.gameObject, endInterface);
// 同时添加到 allConnectionPoints 列表
if (allConnectionPoints != null && !allConnectionPoints.Contains(child.gameObject))
{
allConnectionPoints.Add(child.gameObject);
}
registeredCount++;
}
else if (debugMode)
{
Debug.Log($"终点接口为 null跳过堆叠注册: {child.name}");
}
}
}
if (debugMode)
{
int startCount = startInterface != null ? GetStackCountForInterface(interfaceStacks, startInterface) : 0;
int endCount = endInterface != null ? GetStackCountForInterface(interfaceStacks, endInterface) : 0;
Debug.Log($"连接点堆叠注册完成 - 注册了 {registeredCount} 个连接点");
Debug.Log($"起点接口: {startInterface?.name ?? "null"} ({startCount}个), 终点接口: {endInterface?.name ?? "null"} ({endCount}个)");
Debug.Log($"allConnectionPoints 列表总数: {allConnectionPoints?.Count ?? 0}");
// 打印所有接口的堆叠状态
Debug.Log("=== 所有接口堆叠状态 ===");
foreach (var kvp in interfaceStacks)
{
Debug.Log($"接口: {kvp.Key}, 连接点数量: {kvp.Value.Count}");
}
Debug.Log("=== 堆叠状态结束 ===");
}
}
catch (System.Exception e)
{
Debug.LogError($"注册连接点到堆叠系统失败: {e.Message}");
}
}
/// <summary>
/// 验证堆叠限制是否正常工作
/// </summary>
public void ValidateStackingSystem()
{
if (wireSystem == null)
{
Debug.LogError("WireSystem 为 null无法验证堆叠系统");
return;
}
try
{
// 获取 WireDrawingSystem 中的 interfaceStacks 字典
var interfaceStacksField = typeof(WireDrawingSystem).GetField("interfaceStacks",
BindingFlags.NonPublic | BindingFlags.Instance);
if (interfaceStacksField == null)
{
Debug.LogError("无法找到 interfaceStacks 字段");
return;
}
var interfaceStacks = (Dictionary<string, List<GameObject>>)interfaceStacksField.GetValue(wireSystem);
// 获取最大堆叠数量
var maxStackCountField = typeof(WireDrawingSystem).GetField("maxStackCount",
BindingFlags.Public | BindingFlags.Instance);
int maxStackCount = maxStackCountField != null ? (int)maxStackCountField.GetValue(wireSystem) : 5;
Debug.Log("=== 堆叠系统验证 ===");
Debug.Log($"最大堆叠数量: {maxStackCount}");
Debug.Log($"接口数量: {interfaceStacks.Count}");
// 检查每个接口的堆叠状态
foreach (var kvp in interfaceStacks)
{
string interfaceObj = kvp.Key;
List<GameObject> connectionPoints = kvp.Value;
// 清理已销毁的连接点
connectionPoints.RemoveAll(item => item == null);
Debug.Log($"接口: {interfaceObj}, 连接点数量: {connectionPoints.Count}, 是否达到限制: {connectionPoints.Count >= maxStackCount}");
// 验证每个连接点是否都有正确的引用
foreach (GameObject point in connectionPoints)
{
if (point != null)
{
ConnectionPointInterfaceReference refComponent = point.GetComponent<ConnectionPointInterfaceReference>();
if (refComponent == null || refComponent.targetInterface == null)
{
Debug.LogWarning($"连接点 {point.name} 缺少有效的接口引用");
}
}
}
}
Debug.Log("=== 验证结束 ===");
}
catch (System.Exception e)
{
Debug.LogError($"验证堆叠系统失败: {e.Message}");
}
}
/// <summary>
/// 注册单个连接点到接口堆叠系统
/// </summary>
private void RegisterConnectionPointWithInterface(Dictionary<string, List<GameObject>> interfaceStacks,
GameObject connectionPoint, GameObject targetInterface)
{
if (targetInterface == null) return;
// 确保接口在字典中存在
if (!interfaceStacks.ContainsKey(targetInterface.name))
{
interfaceStacks[targetInterface.name] = new List<GameObject>();
if (debugMode) Debug.Log($"为接口 {targetInterface.name} 创建新堆叠列表");
}
// 添加连接点到堆叠列表
if (!interfaceStacks[targetInterface.name].Contains(connectionPoint))
{
interfaceStacks[targetInterface.name].Add(connectionPoint);
if (debugMode) Debug.Log($"连接点 {connectionPoint.name} 已注册到接口 {targetInterface.name},当前总数: {interfaceStacks[targetInterface.name].Count}");
}
// 确保连接点有 ConnectionPointInterfaceReference 组件
ConnectionPointInterfaceReference refComponent = connectionPoint.GetComponent<ConnectionPointInterfaceReference>();
if (refComponent == null)
{
refComponent = connectionPoint.AddComponent<ConnectionPointInterfaceReference>();
}
refComponent.targetInterface = targetInterface;
}
/// <summary>
/// 获取接口上的连接点数量
/// </summary>
private int GetStackCountForInterface(Dictionary<string, List<GameObject>> interfaceStacks, GameObject targetInterface)
{
if (targetInterface == null || !interfaceStacks.ContainsKey(targetInterface.name))
{
return 0;
}
// 清理已销毁的模型引用
interfaceStacks[targetInterface.name].RemoveAll(item => item == null);
return interfaceStacks[targetInterface.name].Count;
}
/// <summary>
/// 使用反射设置 CylinderWireData 的所有字段 - 修复版
/// </summary>
private void SetCylinderWireDataFields(CylinderWireData cylinderData, SerializableWireConnectionData wireData,
GameObject startInterface, GameObject endInterface)
{
try
{
// 获取 CylinderWireData 类型的所有字段
FieldInfo[] fields = typeof(CylinderWireData).GetFields(BindingFlags.Public | BindingFlags.Instance);
if (debugMode) Debug.Log($"CylinderWireData 有 {fields.Length} 个公共字段");
// 首先设置基本的连接点信息
foreach (FieldInfo field in fields)
{
try
{
// 根据字段名称设置对应的值
switch (field.Name)
{
case "startPoint":
// 使用保存的起点位置
field.SetValue(cylinderData, wireData.startPoint);
if (debugMode) Debug.Log($"设置 startPoint: {wireData.startPoint}");
break;
case "endPoint":
// 使用保存的终点位置
field.SetValue(cylinderData, wireData.endPoint);
if (debugMode) Debug.Log($"设置 endPoint: {wireData.endPoint}");
break;
case "snapStartObject":
case "startInterface":
// 设置起点接口
field.SetValue(cylinderData, startInterface);
if (debugMode) Debug.Log($"设置 snapStartObject/startInterface: {startInterface?.name ?? "null"}");
break;
case "snapEndObject":
case "endInterface":
// 设置终点接口
field.SetValue(cylinderData, endInterface);
if (debugMode) Debug.Log($"设置 snapEndObject/endInterface: {endInterface?.name ?? "null"}");
break;
case "creationTime":
// 使用保存的创建时间
field.SetValue(cylinderData, wireData.creationTime);
if (debugMode) Debug.Log($"设置 creationTime: {wireData.creationTime}");
break;
case "wireDiameter":
// 使用保存的圆柱体半径计算直径,或使用默认值
float diameter = wireData.cylinderRadius > 0 ? wireData.cylinderRadius * 2f : 0.02f;
field.SetValue(cylinderData, diameter);
if (debugMode) Debug.Log($"设置 wireDiameter: {diameter} (从半径 {wireData.cylinderRadius} 计算)");
break;
default:
// 尝试设置其他字段
if (debugMode) Debug.Log($"跳过字段: {field.Name} (类型: {field.FieldType})");
break;
}
}
catch (System.Exception e)
{
Debug.LogWarning($"设置字段 {field.Name} 失败: {e.Message}");
}
}
// 额外设置一些可能需要的属性
SetAdditionalCylinderWireProperties(cylinderData, wireData);
}
catch (System.Exception e)
{
Debug.LogError($"设置 CylinderWireData 字段失败: {e.Message}");
}
}
/// <summary>
/// 设置额外的圆柱体连线属性
/// </summary>
private void SetAdditionalCylinderWireProperties(CylinderWireData cylinderData, SerializableWireConnectionData wireData)
{
try
{
// 使用反射设置可能存在的其他属性
PropertyInfo[] properties = typeof(CylinderWireData).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo property in properties)
{
try
{
if (property.CanWrite)
{
switch (property.Name)
{
case "WireColor":
// 如果有自定义颜色,设置连线颜色
if (wireData.hasCustomColor)
{
Color wireColor = new Color(wireData.wireColorR, wireData.wireColorG, wireData.wireColorB, wireData.wireColorA);
property.SetValue(cylinderData, wireColor);
if (debugMode) Debug.Log($"设置 WireColor: {wireColor}");
}
break;
// 可以根据需要添加更多属性设置
}
}
}
catch (System.Exception e)
{
Debug.LogWarning($"设置属性 {property.Name} 失败: {e.Message}");
}
}
}
catch (System.Exception e)
{
Debug.LogError($"设置额外圆柱体连线属性失败: {e.Message}");
}
}
/// <summary>
/// 创建圆柱体视觉表现 - 使用保存的圆柱体数据和颜色
/// </summary>
private void CreateCylinderVisual(GameObject wireObject, SerializableWireConnectionData wireData)
{
try
{
// 创建圆柱体
GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
if (cylinder == null)
{
Debug.LogError("创建圆柱体失败");
return;
}
cylinder.name = "WireCylinder";
cylinder.transform.SetParent(wireObject.transform);
// 使用保存的圆柱体数据
if (wireData.cylinderScale != Vector3.zero)
{
// 使用保存的缩放
cylinder.transform.localScale = wireData.cylinderScale;
if (debugMode) Debug.Log($"使用保存的圆柱体缩放: {wireData.cylinderScale}");
}
else
{
// 计算连线的方向、距离和中点
Vector3 startPoint = wireData.startPoint;
Vector3 endPoint = wireData.endPoint;
Vector3 direction = (endPoint - startPoint).normalized;
float distance = Vector3.Distance(startPoint, endPoint);
Vector3 midpoint = (startPoint + endPoint) / 2;
// 设置圆柱体的位置为中点
cylinder.transform.position = midpoint;
// 计算正确的旋转
if (direction != Vector3.zero)
{
// 圆柱体默认朝向是Y轴我们需要让它朝向连线方向
cylinder.transform.rotation = Quaternion.LookRotation(direction);
// 圆柱体需要绕X轴旋转90度因为圆柱体默认是立着的
cylinder.transform.Rotate(90, 0, 0, Space.Self);
}
// 设置圆柱体缩放 - 使用保存的半径或默认值
float radius = wireData.cylinderRadius > 0 ? wireData.cylinderRadius : 0.02f;
cylinder.transform.localScale = new Vector3(
radius, // X轴 - 半径
distance / 2, // Y轴 - 高度的一半因为默认高度是2
radius // Z轴 - 半径
);
if (debugMode) Debug.Log($"使用计算的圆柱体缩放: {cylinder.transform.localScale}");
}
// 使用保存的位置和旋转(如果存在)
if (wireData.cylinderPosition != Vector3.zero)
{
cylinder.transform.position = wireData.cylinderPosition;
if (debugMode) Debug.Log($"使用保存的圆柱体位置: {wireData.cylinderPosition}");
}
if (wireData.cylinderRotation != Quaternion.identity)
{
cylinder.transform.rotation = wireData.cylinderRotation;
if (debugMode) Debug.Log($"使用保存的圆柱体旋转: {wireData.cylinderRotation}");
}
// 设置材质和颜色
Renderer renderer = cylinder.GetComponent<Renderer>();
if (renderer != null)
{
if (cylinderWireMaterial != null)
{
// 使用实例化材质以便单独设置颜色
Material wireMaterial = new Material(cylinderWireMaterial);
// 如果保存了自定义颜色,使用保存的颜色;否则使用默认颜色
if (wireData.hasCustomColor)
{
Color savedColor = new Color(
wireData.wireColorR,
wireData.wireColorG,
wireData.wireColorB,
wireData.wireColorA
);
wireMaterial.color = savedColor;
if (debugMode) Debug.Log($"应用保存的连线颜色: {savedColor}");
}
else
{
wireMaterial.color = defaultWireColor;
if (debugMode) Debug.Log($"应用默认连线颜色: {defaultWireColor}");
}
renderer.material = wireMaterial;
}
else
{
// 如果没有指定材质,直接设置颜色
if (wireData.hasCustomColor)
{
Color savedColor = new Color(
wireData.wireColorR,
wireData.wireColorG,
wireData.wireColorB,
wireData.wireColorA
);
renderer.material.color = savedColor;
}
else
{
renderer.material.color = defaultWireColor;
}
}
}
// 移除碰撞器
Collider collider = cylinder.GetComponent<Collider>();
if (collider != null)
{
DestroyImmediate(collider);
}
if (debugMode) Debug.Log($"圆柱体视觉创建完成: 位置={cylinder.transform.position}, 缩放={cylinder.transform.localScale}, 颜色={renderer.material.color}");
}
catch (System.Exception e)
{
Debug.LogError($"创建圆柱体视觉失败: {e.Message}");
}
}
/// <summary>
/// 为连线创建连接点 - 恢复连接点样式,返回创建的连接点列表
/// </summary>
private List<GameObject> CreateConnectionPointsForWire(GameObject wireObject, SerializableWireConnectionData wireData,
GameObject startInterface, GameObject endInterface)
{
List<GameObject> connectionPoints = new List<GameObject>();
try
{
// 通过反射获取连接点预制体
var connectionPointPrefabField = typeof(WireDrawingSystem).GetField("connectionPointPrefab",
BindingFlags.Public | BindingFlags.Instance);
GameObject connectionPointPrefab = connectionPointPrefabField != null ?
(GameObject)connectionPointPrefabField.GetValue(wireSystem) : null;
if (connectionPointPrefab != null)
{
// 创建起点连接点
if (wireData.startConnectionPointPosition != Vector3.zero)
{
GameObject startConnectionPoint = CreateConnectionPoint(
wireData.startConnectionPointPosition,
"ConnectionPoint_Start_Restored",
connectionPointPrefab,
wireData.connectionPointScale,
new Color(wireData.startPointColorR, wireData.startPointColorG, wireData.startPointColorB),
true
);
if (startConnectionPoint != null)
{
startConnectionPoint.transform.SetParent(wireObject.transform);
connectionPoints.Add(startConnectionPoint);
}
}
// 创建终点连接点
if (wireData.endConnectionPointPosition != Vector3.zero)
{
GameObject endConnectionPoint = CreateConnectionPoint(
wireData.endConnectionPointPosition,
"ConnectionPoint_End_Restored",
connectionPointPrefab,
wireData.connectionPointScale,
new Color(wireData.endPointColorR, wireData.endPointColorG, wireData.endPointColorB),
false
);
if (endConnectionPoint != null)
{
endConnectionPoint.transform.SetParent(wireObject.transform);
connectionPoints.Add(endConnectionPoint);
}
}
}
}
catch (System.Exception e)
{
Debug.LogWarning($"创建连接点失败: {e.Message}");
}
return connectionPoints;
}
/// <summary>
/// 创建连接点 - 支持颜色和样式恢复
/// </summary>
private GameObject CreateConnectionPoint(Vector3 position, string name, GameObject prefab, float scale, Color color, bool isStartPoint)
{
if (prefab == null) return null;
GameObject connectionPoint = Instantiate(prefab);
connectionPoint.name = name;
connectionPoint.transform.position = position;
// 设置缩放
try
{
connectionPoint.transform.localScale = Vector3.one * scale;
if (debugMode) Debug.Log($"设置连接点缩放: {scale}");
}
catch
{
connectionPoint.transform.localScale = Vector3.one * 0.1f;
}
// 设置材质和颜色
try
{
Renderer renderer = connectionPoint.GetComponent<Renderer>();
if (renderer != null)
{
if (defaultConnectionPointMaterial != null)
{
// 使用实例化材质以便单独设置颜色
Material pointMaterial = new Material(defaultConnectionPointMaterial);
pointMaterial.color = color;
renderer.material = pointMaterial;
if (debugMode) Debug.Log($"应用连接点颜色: {color} ({(isStartPoint ? "" : "")})");
}
else
{
// 直接设置材质颜色
renderer.material.color = color;
}
}
}
catch (System.Exception e)
{
Debug.LogWarning($"设置连接点材质失败: {e.Message}");
}
return connectionPoint;
}
/// <summary>
/// 将连线添加到连线系统
/// </summary>
private void AddWireToSystem(GameObject wireObject, SerializableWireConnectionData wireData,
GameObject startInterface, GameObject endInterface)
{
try
{
// 通过反射访问连线系统的内部列表
var allWiresField = typeof(WireDrawingSystem).GetField("allWires",
BindingFlags.NonPublic | BindingFlags.Instance);
var allConnectionPointsField = typeof(WireDrawingSystem).GetField("allConnectionPoints",
BindingFlags.NonPublic | BindingFlags.Instance);
if (allWiresField != null)
{
List<GameObject> allWires = (List<GameObject>)allWiresField.GetValue(wireSystem);
if (allWires != null)
{
allWires.Add(wireObject);
}
}
// 添加连接点到列表
if (allConnectionPointsField != null)
{
List<GameObject> allConnectionPoints = (List<GameObject>)allConnectionPointsField.GetValue(wireSystem);
if (allConnectionPoints != null)
{
foreach (Transform child in wireObject.transform)
{
if (child.name.StartsWith("ConnectionPoint_"))
{
allConnectionPoints.Add(child.gameObject);
}
}
}
}
if (debugMode) Debug.Log($"连线已添加到系统: {wireData.wireName}");
}
catch (System.Exception e)
{
Debug.LogError($"添加连线到系统失败: {e.Message}");
}
}
/// <summary>
/// 获取连线的连接数据 - 关键修复方法,保存圆柱体数据和颜色
/// </summary>
private SerializableWireConnectionData GetWireConnectionData(GameObject wireObject)
{
try
{
if (wireObject == null)
{
if (debugMode) Debug.LogWarning("连线对象为 null");
return null;
}
// 方法1首先尝试从 CylinderWireData 组件获取
CylinderWireData cylinderData = wireObject.GetComponent<CylinderWireData>();
if (cylinderData != null)
{
SerializableWireConnectionData connectionData = new SerializableWireConnectionData
{
wireName = wireObject.name,
creationTime = System.DateTime.Now,
debugInfo = "从 CylinderWireData 组件获取",
wireType = "CylinderWireData"
};
// 使用反射获取所有字段
FieldInfo[] fields = typeof(CylinderWireData).GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
try
{
switch (field.Name)
{
case "startPoint":
connectionData.startPoint = (Vector3)field.GetValue(cylinderData);
break;
case "endPoint":
connectionData.endPoint = (Vector3)field.GetValue(cylinderData);
break;
case "startInterface":
GameObject startInterface = (GameObject)field.GetValue(cylinderData);
connectionData.startInterfaceName = startInterface ? startInterface.name : "";
connectionData.hasStartInterface = startInterface != null;
break;
case "endInterface":
GameObject endInterface = (GameObject)field.GetValue(cylinderData);
connectionData.endInterfaceName = endInterface ? endInterface.name : "";
connectionData.hasEndInterface = endInterface != null;
break;
}
}
catch (System.Exception e)
{
Debug.LogWarning($"获取字段 {field.Name} 失败: {e.Message}");
}
}
// 查找圆柱体子物体并保存其数据和颜色
Transform cylinderChild = wireObject.transform.Find("WireCylinder");
if (cylinderChild != null)
{
connectionData.cylinderScale = cylinderChild.localScale;
connectionData.cylinderPosition = cylinderChild.position;
connectionData.cylinderRotation = cylinderChild.rotation;
// 计算圆柱体半径取X和Z缩放的平均值
connectionData.cylinderRadius = (cylinderChild.localScale.x + cylinderChild.localScale.z) / 2f;
// 保存圆柱体颜色
Renderer cylinderRenderer = cylinderChild.GetComponent<Renderer>();
if (cylinderRenderer != null && cylinderRenderer.material != null)
{
Color wireColor = cylinderRenderer.material.color;
connectionData.wireColorR = wireColor.r;
connectionData.wireColorG = wireColor.g;
connectionData.wireColorB = wireColor.b;
connectionData.wireColorA = wireColor.a;
connectionData.hasCustomColor = true;
if (debugMode) Debug.Log($"保存连线颜色: {wireColor}");
}
if (debugMode)
{
Debug.Log($"保存圆柱体数据: 缩放={connectionData.cylinderScale}, 位置={connectionData.cylinderPosition}, 半径={connectionData.cylinderRadius}");
}
}
// 查找连接点的位置、缩放和颜色
foreach (Transform child in wireObject.transform)
{
if (child.name.StartsWith("ConnectionPoint_Start"))
{
connectionData.startConnectionPointPosition = child.position;
connectionData.connectionPointScale = child.localScale.x; // 假设均匀缩放
// 保存起点连接点颜色
Renderer startRenderer = child.GetComponent<Renderer>();
if (startRenderer != null && startRenderer.material != null)
{
Color startColor = startRenderer.material.color;
connectionData.startPointColorR = startColor.r;
connectionData.startPointColorG = startColor.g;
connectionData.startPointColorB = startColor.b;
}
}
else if (child.name.StartsWith("ConnectionPoint_End"))
{
connectionData.endConnectionPointPosition = child.position;
// 保存终点连接点颜色
Renderer endRenderer = child.GetComponent<Renderer>();
if (endRenderer != null && endRenderer.material != null)
{
Color endColor = endRenderer.material.color;
connectionData.endPointColorR = endColor.r;
connectionData.endPointColorG = endColor.g;
connectionData.endPointColorB = endColor.b;
}
}
}
if (debugMode)
{
Debug.Log($"从 CylinderWireData 组件获取连线数据: {connectionData.wireName}");
Debug.Log($"起点: {connectionData.startPoint}, 终点: {connectionData.endPoint}");
Debug.Log($"起点接口: {connectionData.startInterfaceName}, 终点接口: {connectionData.endInterfaceName}");
Debug.Log($"连线颜色: {connectionData.hasCustomColor}");
}
return connectionData;
}
// 方法2尝试从 WireData 组件获取(兼容旧版本)
WireData wireDataComponent = wireObject.GetComponent<WireData>();
if (wireDataComponent != null)
{
SerializableWireConnectionData connectionData = new SerializableWireConnectionData
{
startInterfaceName = wireDataComponent.snapStartObject ? wireDataComponent.snapStartObject.name : "",
endInterfaceName = wireDataComponent.snapEndObject ? wireDataComponent.snapEndObject.name : "",
startPoint = wireDataComponent.startPoint,
endPoint = wireDataComponent.endPoint,
wireName = wireObject.name,
creationTime = wireDataComponent.creationTime,
hasStartInterface = wireDataComponent.snapStartObject != null,
hasEndInterface = wireDataComponent.snapEndObject != null,
debugInfo = "从 WireData 组件获取",
wireType = "WireData"
};
// 查找连接点的位置、缩放和颜色
foreach (Transform child in wireObject.transform)
{
if (child.name.StartsWith("ConnectionPoint_Start"))
{
connectionData.startConnectionPointPosition = child.position;
connectionData.connectionPointScale = child.localScale.x;
Renderer startRenderer = child.GetComponent<Renderer>();
if (startRenderer != null && startRenderer.material != null)
{
Color startColor = startRenderer.material.color;
connectionData.startPointColorR = startColor.r;
connectionData.startPointColorG = startColor.g;
connectionData.startPointColorB = startColor.b;
}
}
else if (child.name.StartsWith("ConnectionPoint_End"))
{
connectionData.endConnectionPointPosition = child.position;
Renderer endRenderer = child.GetComponent<Renderer>();
if (endRenderer != null && endRenderer.material != null)
{
Color endColor = endRenderer.material.color;
connectionData.endPointColorR = endColor.r;
connectionData.endPointColorG = endColor.g;
connectionData.endPointColorB = endColor.b;
}
}
}
// 尝试获取连线颜色
Transform wireVisual = wireObject.transform.Find("WireCylinder");
if (wireVisual != null)
{
Renderer wireRenderer = wireVisual.GetComponent<Renderer>();
if (wireRenderer != null && wireRenderer.material != null)
{
Color wireColor = wireRenderer.material.color;
connectionData.wireColorR = wireColor.r;
connectionData.wireColorG = wireColor.g;
connectionData.wireColorB = wireColor.b;
connectionData.wireColorA = wireColor.a;
connectionData.hasCustomColor = true;
}
}
if (debugMode) Debug.Log($"从 WireData 组件获取连线数据: {connectionData.wireName}");
return connectionData;
}
if (debugMode) Debug.LogWarning($"无法获取连线数据: {wireObject.name},所有方法都失败");
return null;
}
catch (System.Exception e)
{
Debug.LogError($"获取连线数据失败: {e.Message}");
return null;
}
}
/// <summary>
/// 根据名称查找接口对象 - 增强查找能力
/// </summary>
private GameObject FindInterfaceByName(string interfaceName)
{
if (string.IsNullOrEmpty(interfaceName))
{
if (debugMode) Debug.LogWarning("接口名称为空");
return null;
}
// 方法1直接通过名称查找
GameObject obj = GameObject.Find(interfaceName);
if (obj != null)
{
if (debugMode) Debug.Log($"通过名称找到接口: {interfaceName}");
return obj;
}
// 方法2在场景中查找包含该名称的对象
GameObject[] allObjects = GameObject.FindObjectsOfType<GameObject>();
foreach (GameObject gameObj in allObjects)
{
if (gameObj.name.Contains(interfaceName))
{
if (debugMode) Debug.Log($"通过包含名称找到接口: {interfaceName} -> {gameObj.name}");
return gameObj;
}
}
// 方法3通过标签查找如果有特定标签
try
{
GameObject[] taggedObjs = GameObject.FindGameObjectsWithTag("Interface");
foreach (GameObject taggedObj in taggedObjs)
{
if (taggedObj.name == interfaceName)
{
if (debugMode) Debug.Log($"通过标签找到接口: {interfaceName}");
return taggedObj;
}
}
}
catch { }
if (debugMode) Debug.LogWarning($"WireDataPersistence: 找不到接口物体: {interfaceName}");
return null;
}
/// <summary>
/// 手动保存
/// </summary>
public void ManualSave()
{
SaveWireData();
}
/// <summary>
/// 手动加载
/// </summary>
public void ManualLoad()
{
LoadWireData();
}
/// <summary>
/// 清除所有保存的数据
/// </summary>
public void ClearSavedData()
{
if (File.Exists(saveFilePath))
{
File.Delete(saveFilePath);
if (debugMode) Debug.Log("WireDataPersistence: 已清除保存的数据文件");
}
}
/// <summary>
/// 获取保存信息
/// </summary>
public string GetSaveInfo()
{
if (File.Exists(saveFilePath))
{
FileInfo fileInfo = new FileInfo(saveFilePath);
try
{
string jsonData = File.ReadAllText(saveFilePath);
SerializableWireData data = JsonUtility.FromJson<SerializableWireData>(jsonData);
int coloredWires = data.wires.Count(w => w.hasCustomColor);
return $"WireDataPersistence: 已保存 {data.wires.Count} 条连线 ({coloredWires} 条有颜色), 文件大小: {fileInfo.Length} 字节, 路径: {saveFilePath}";
}
catch
{
return $"WireDataPersistence: 文件存在但读取失败, 大小: {fileInfo.Length} 字节";
}
}
else
{
return "WireDataPersistence: 暂无保存数据";
}
}
/// <summary>
/// 检查是否有保存的数据
/// </summary>
public bool HasSavedData()
{
return File.Exists(saveFilePath);
}
/// <summary>
/// 获取保存文件路径
/// </summary>
public string GetSaveFilePath()
{
return saveFilePath;
}
/// <summary>
/// 获取当前连线的统计信息
/// </summary>
public string GetWireStats()
{
if (!isInitialized || wireSystem == null) return "系统未初始化";
try
{
var allWiresField = typeof(WireDrawingSystem).GetField("allWires",
BindingFlags.NonPublic | BindingFlags.Instance);
if (allWiresField == null) return "无法访问连线数据";
List<GameObject> allWires = (List<GameObject>)allWiresField.GetValue(wireSystem);
// 统计连线类型
int cylinderCount = 0;
int lineRendererCount = 0;
int unknownCount = 0;
int coloredWires = 0;
if (allWires != null)
{
foreach (var wire in allWires)
{
if (wire != null)
{
if (wire.GetComponent<CylinderWireData>() != null) cylinderCount++;
else if (wire.GetComponent<LineRenderer>() != null) lineRendererCount++;
else unknownCount++;
// 检查是否有自定义颜色
Transform cylinder = wire.transform.Find("WireCylinder");
if (cylinder != null)
{
Renderer renderer = cylinder.GetComponent<Renderer>();
if (renderer != null && renderer.material != null && renderer.material.color != defaultWireColor)
{
coloredWires++;
}
}
}
}
}
return $"当前场景中有 {allWires?.Count ?? 0} 条连线 (圆柱体: {cylinderCount}, LineRenderer: {lineRendererCount}, 未知: {unknownCount}, 有颜色: {coloredWires})";
}
catch (System.Exception e)
{
return $"获取统计信息失败: {e.Message}";
}
}
/// <summary>
/// 测试特定接口的堆叠限制
/// </summary>
public void TestStackingLimit(string interfaceName)
{
if (wireSystem == null)
{
Debug.LogError("WireSystem 为 null无法测试堆叠限制");
return;
}
try
{
// 获取 WireDrawingSystem 中的 interfaceStacks 字典
var interfaceStacksField = typeof(WireDrawingSystem).GetField("interfaceStacks",
BindingFlags.NonPublic | BindingFlags.Instance);
if (interfaceStacksField == null)
{
Debug.LogError("无法找到 interfaceStacks 字段");
return;
}
var interfaceStacks = (Dictionary<GameObject, List<GameObject>>)interfaceStacksField.GetValue(wireSystem);
// 查找接口
GameObject targetInterface = null;
foreach (var kvp in interfaceStacks)
{
if (kvp.Key.name == interfaceName)
{
targetInterface = kvp.Key;
break;
}
}
if (targetInterface == null)
{
Debug.LogWarning($"找不到接口: {interfaceName}");
return;
}
// 获取堆叠检查方法
var isStackLimitReachedMethod = typeof(WireDrawingSystem).GetMethod("IsStackLimitReached",
BindingFlags.NonPublic | BindingFlags.Instance);
if (isStackLimitReachedMethod == null)
{
Debug.LogError("无法找到 IsStackLimitReached 方法");
return;
}
bool isLimitReached = (bool)isStackLimitReachedMethod.Invoke(wireSystem, new object[] { targetInterface });
Debug.Log($"堆叠限制测试 - 接口: {interfaceName}, 是否达到限制: {isLimitReached}");
}
catch (System.Exception e)
{
Debug.LogError($"测试堆叠限制失败: {e.Message}");
}
}
/// <summary>
/// 强制立即保存
/// </summary>
public void ForceSave()
{
SaveWireData();
}
}