ND_SimulationAutomaticControl/Assets/Scripts/Line/WireDataPersistence.cs

1150 lines
39 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 UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
// 可序列化的连线数据
[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 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; // 圆柱体连线材质
[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();
}
}
/// <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()} 条");
}
}
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})");
}
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()} 条");
}
}
}
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()} 条");
}
}
// 如果 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();
}
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})");
// 查找接口物体
GameObject startInterface = FindInterfaceByName(wireData.startInterfaceName);
GameObject endInterface = FindInterfaceByName(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 组件并设置数据
CylinderWireData cylinderData = wireObject.AddComponent<CylinderWireData>();
// 使用反射设置 CylinderWireData 的所有字段
SetCylinderWireDataFields(cylinderData, wireData, startInterface, endInterface);
// 创建圆柱体视觉表现 - 使用保存的圆柱体数据
CreateCylinderVisual(wireObject, wireData);
// 创建连接点
CreateConnectionPointsForWire(wireObject, wireData, startInterface, endInterface);
// 添加到连线系统
AddWireToSystem(wireObject, wireData, startInterface, endInterface);
if (debugMode)
{
Debug.Log($"WireDataPersistence: 成功重建圆柱体连线: {wireData.wireName}");
Debug.Log($"圆柱体缩放: {wireData.cylinderScale}, 位置: {wireData.cylinderPosition}");
}
return true;
}
catch (System.Exception e)
{
Debug.LogError($"重建圆柱体连线失败: {e.Message}");
return false;
}
}
/// <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":
field.SetValue(cylinderData, startInterface);
if (debugMode) Debug.Log($"设置 snapStartObject: {startInterface?.name ?? "null"}");
break;
case "snapEndObject":
field.SetValue(cylinderData, endInterface);
if (debugMode) Debug.Log($"设置 snapEndObject: {endInterface?.name ?? "null"}");
break;
case "creationTime":
field.SetValue(cylinderData, wireData.creationTime);
if (debugMode) Debug.Log($"设置 creationTime: {wireData.creationTime}");
break;
default:
// 尝试设置其他字段
if (debugMode) Debug.Log($"跳过字段: {field.Name} (类型: {field.FieldType})");
break;
}
}
catch (System.Exception e)
{
Debug.LogWarning($"设置字段 {field.Name} 失败: {e.Message}");
}
}
}
catch (System.Exception e)
{
Debug.LogError($"设置 CylinderWireData 字段失败: {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}");
}
// 设置材质
if (cylinderWireMaterial != null)
{
Renderer renderer = cylinder.GetComponent<Renderer>();
if (renderer != null)
{
renderer.material = cylinderWireMaterial;
}
}
// 移除碰撞器
Collider collider = cylinder.GetComponent<Collider>();
if (collider != null)
{
DestroyImmediate(collider);
}
if (debugMode) Debug.Log($"圆柱体视觉创建完成: 位置={cylinder.transform.position}, 缩放={cylinder.transform.localScale}");
}
catch (System.Exception e)
{
Debug.LogError($"创建圆柱体视觉失败: {e.Message}");
}
}
/// <summary>
/// 为连线创建连接点
/// </summary>
private void CreateConnectionPointsForWire(GameObject wireObject, SerializableWireConnectionData wireData,
GameObject startInterface, GameObject endInterface)
{
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
);
if (startConnectionPoint != null)
{
startConnectionPoint.transform.SetParent(wireObject.transform);
}
}
// 创建终点连接点
if (wireData.endConnectionPointPosition != Vector3.zero)
{
GameObject endConnectionPoint = CreateConnectionPoint(
wireData.endConnectionPointPosition,
"ConnectionPoint_End_Restored",
connectionPointPrefab
);
if (endConnectionPoint != null)
{
endConnectionPoint.transform.SetParent(wireObject.transform);
}
}
}
}
catch (System.Exception e)
{
Debug.LogWarning($"创建连接点失败: {e.Message}");
}
}
/// <summary>
/// 创建连接点
/// </summary>
private GameObject CreateConnectionPoint(Vector3 position, string name, GameObject prefab)
{
if (prefab == null) return null;
GameObject connectionPoint = Instantiate(prefab);
connectionPoint.name = name;
connectionPoint.transform.position = position;
// 设置缩放
try
{
var connectionPointScaleField = typeof(WireDrawingSystem).GetField("connectionPointScale",
BindingFlags.Public | BindingFlags.Instance);
float connectionPointScale = connectionPointScaleField != null ?
(float)connectionPointScaleField.GetValue(wireSystem) : 0.1f;
connectionPoint.transform.localScale = Vector3.one * connectionPointScale;
}
catch
{
connectionPoint.transform.localScale = Vector3.one * 0.1f;
}
// 设置材质
try
{
var connectionPointMaterialField = typeof(WireDrawingSystem).GetField("connectionPointMaterial",
BindingFlags.Public | BindingFlags.Instance);
Material connectionPointMaterial = connectionPointMaterialField != null ?
(Material)connectionPointMaterialField.GetValue(wireSystem) : null;
if (connectionPointMaterial != null)
{
Renderer renderer = connectionPoint.GetComponent<Renderer>();
if (renderer != null)
{
renderer.material = connectionPointMaterial;
}
}
}
catch
{
// 忽略材质设置错误
}
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 "snapStartObject":
GameObject startInterface = (GameObject)field.GetValue(cylinderData);
connectionData.startInterfaceName = startInterface ? startInterface.name : "";
connectionData.hasStartInterface = startInterface != null;
break;
case "snapEndObject":
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;
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;
}
else if (child.name.StartsWith("ConnectionPoint_End"))
{
connectionData.endConnectionPointPosition = child.position;
}
}
if (debugMode)
{
Debug.Log($"从 CylinderWireData 组件获取连线数据: {connectionData.wireName}");
Debug.Log($"起点: {connectionData.startPoint}, 终点: {connectionData.endPoint}");
}
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;
}
else if (child.name.StartsWith("ConnectionPoint_End"))
{
connectionData.endConnectionPointPosition = child.position;
}
}
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))
return null;
// 在场景中查找物体
GameObject obj = GameObject.Find(interfaceName);
if (obj == null && debugMode)
{
Debug.LogWarning($"WireDataPersistence: 找不到接口物体: {interfaceName}");
}
return obj;
}
/// <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);
return $"WireDataPersistence: 已保存 {data.wires.Count} 条连线, 文件大小: {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;
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++;
}
}
}
return $"当前场景中有 {allWires?.Count ?? 0} 条连线 (圆柱体: {cylinderCount}, LineRenderer: {lineRendererCount}, 未知: {unknownCount})";
}
catch (System.Exception e)
{
return $"获取统计信息失败: {e.Message}";
}
}
/// <summary>
/// 强制立即保存
/// </summary>
public void ForceSave()
{
SaveWireData();
}
//void OnApplicationQuit()
//{
// // 程序退出时自动保存
// if (enableAutoSave && isInitialized)
// {
// if (debugMode) Debug.Log("WireDataPersistence: 程序退出,保存数据");
// //SaveWireData();
// }
//}
//void OnDestroy()
//{
// // 组件销毁时自动保存
// if (enableAutoSave && isInitialized)
// {
// if (debugMode) Debug.Log("WireDataPersistence: 组件销毁,保存数据");
// //SaveWireData();
// }
//}
//void OnApplicationPause(bool pauseStatus)
//{
// // 应用暂停时保存(移动设备)
// if (pauseStatus && enableAutoSave && isInitialized)
// {
// if (debugMode) Debug.Log("WireDataPersistence: 应用暂停,保存数据");
// // SaveWireData();
// }
//}
}