2236 lines
82 KiB
C#
2236 lines
82 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using UnityEngine;
|
||
using UnityEngine.UIElements;
|
||
using UnityEngine.Networking;
|
||
|
||
// 可序列化的连线数据
|
||
[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 string startInterfaceStyleName = "";
|
||
public string endInterfaceStyleName = "";
|
||
}
|
||
|
||
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 List<GameObject> interfaceStylePrefabs = new List<GameObject>(); // 接口头样式预制体列表
|
||
public string defaultInterfaceStyleName = "Default"; // 默认接口头样式名称
|
||
|
||
[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("手动加载触发");
|
||
StartCoroutine(LoadWireDataCoroutine());
|
||
}
|
||
|
||
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}");
|
||
|
||
// WebGL中不能使用File.Exists,所以跳过这个检查
|
||
#if !UNITY_WEBGL
|
||
Debug.Log($"文件存在: {File.Exists(saveFilePath)}");
|
||
#endif
|
||
|
||
Debug.Log($"当前连线数量: {GetCurrentWireCount()}");
|
||
Debug.Log($"上次保存连线数量: {lastWireCount}");
|
||
Debug.Log($"系统初始化: {isInitialized}");
|
||
Debug.Log($"连线系统引用: {wireSystem != null}");
|
||
|
||
// 在WebGL中,我们无法直接检查文件存在,但可以尝试加载
|
||
StartCoroutine(CheckFileExistsCoroutine());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查文件是否存在的协程(WebGL兼容)
|
||
/// </summary>
|
||
private IEnumerator CheckFileExistsCoroutine()
|
||
{
|
||
#if UNITY_WEBGL
|
||
yield return StartCoroutine(CheckWebGLFileExists());
|
||
#else
|
||
CheckStandardFileExists();
|
||
#endif
|
||
}
|
||
|
||
/// <summary>
|
||
/// WebGL平台检查文件存在
|
||
/// </summary>
|
||
private IEnumerator CheckWebGLFileExists()
|
||
{
|
||
string webglFilePath = Path.Combine(Application.streamingAssetsPath, saveFileName);
|
||
UnityWebRequest webRequest = UnityWebRequest.Get(webglFilePath);
|
||
yield return webRequest.SendWebRequest();
|
||
|
||
if (webRequest.result == UnityWebRequest.Result.Success)
|
||
{
|
||
Debug.Log($"WebGL文件存在: {webglFilePath}");
|
||
|
||
// 尝试读取文件内容
|
||
string jsonData = webRequest.downloadHandler.text;
|
||
if (!string.IsNullOrEmpty(jsonData))
|
||
{
|
||
ProcessFileContent(jsonData);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("WebGL中没有找到连线数据文件");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 标准平台检查文件存在
|
||
/// </summary>
|
||
private void CheckStandardFileExists()
|
||
{
|
||
if (File.Exists(saveFilePath))
|
||
{
|
||
try
|
||
{
|
||
string jsonData = File.ReadAllText(saveFilePath);
|
||
ProcessFileContent(jsonData);
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError($"读取保存文件失败: {e.Message}");
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理文件内容(通用方法)
|
||
/// </summary>
|
||
private void ProcessFileContent(string jsonData)
|
||
{
|
||
try
|
||
{
|
||
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}");
|
||
|
||
// 显示接口头样式统计
|
||
var startStyleGroups = data.wires.GroupBy(w => w.startInterfaceStyleName);
|
||
var endStyleGroups = data.wires.GroupBy(w => w.endInterfaceStyleName);
|
||
|
||
Debug.Log("=== 起点接口头样式统计 ===");
|
||
foreach (var group in startStyleGroups)
|
||
{
|
||
Debug.Log($"起点样式 '{group.Key}': {group.Count()} 个");
|
||
}
|
||
|
||
Debug.Log("=== 终点接口头样式统计 ===");
|
||
foreach (var group in endStyleGroups)
|
||
{
|
||
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();
|
||
yield return LoadWireDataCoroutine();
|
||
}
|
||
|
||
/// <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}, 起点样式: {wireData.startInterfaceStyleName}, 终点样式: {wireData.endInterfaceStyleName})");
|
||
}
|
||
else
|
||
{
|
||
if (debugMode) Debug.LogWarning($"无法获取连线数据: {wire.name}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
string jsonData = JsonUtility.ToJson(data, true);
|
||
|
||
// WebGL和非WebGL平台使用不同的保存方式
|
||
#if UNITY_WEBGL
|
||
// 在WebGL中使用PlayerPrefs存储数据
|
||
PlayerPrefs.SetString("WireData", jsonData);
|
||
PlayerPrefs.Save();
|
||
#else
|
||
// 确保目录存在
|
||
string directory = Path.GetDirectoryName(saveFilePath);
|
||
if (!Directory.Exists(directory))
|
||
{
|
||
Directory.CreateDirectory(directory);
|
||
}
|
||
|
||
File.WriteAllText(saveFilePath, jsonData);
|
||
#endif
|
||
|
||
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}");
|
||
|
||
// 显示接口头样式统计
|
||
var startStyleGroups = data.wires.GroupBy(w => w.startInterfaceStyleName);
|
||
var endStyleGroups = data.wires.GroupBy(w => w.endInterfaceStyleName);
|
||
|
||
Debug.Log("=== 保存的起点接口头样式 ===");
|
||
foreach (var group in startStyleGroups)
|
||
{
|
||
Debug.Log($"起点样式 '{group.Key}': {group.Count()} 个");
|
||
}
|
||
|
||
Debug.Log("=== 保存的终点接口头样式 ===");
|
||
foreach (var group in endStyleGroups)
|
||
{
|
||
Debug.Log($"终点样式 '{group.Key}': {group.Count()} 个");
|
||
}
|
||
}
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError($"WireDataPersistence: 保存数据失败: {e.Message}\n{e.StackTrace}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从文件加载连线数据 - 协程版本(WebGL兼容)
|
||
/// </summary>
|
||
public IEnumerator LoadWireDataCoroutine()
|
||
{
|
||
if (!isInitialized || wireSystem == null)
|
||
{
|
||
Debug.LogWarning("WireDataPersistence: 系统未初始化,无法加载数据");
|
||
yield break;
|
||
}
|
||
|
||
string jsonData = "";
|
||
|
||
#if UNITY_WEBGL
|
||
// WebGL平台从PlayerPrefs加载数据
|
||
if (PlayerPrefs.HasKey("WireData"))
|
||
{
|
||
jsonData = PlayerPrefs.GetString("WireData");
|
||
}
|
||
else
|
||
{
|
||
// 如果PlayerPrefs中没有数据,尝试从StreamingAssets加载
|
||
yield return StartCoroutine(LoadFromStreamingAssets(saveFileName, result => {
|
||
jsonData = result;
|
||
}));
|
||
}
|
||
#else
|
||
// 非WebGL平台使用文件系统
|
||
if (!File.Exists(saveFilePath))
|
||
{
|
||
if (debugMode) Debug.Log("WireDataPersistence: 没有找到连线数据文件");
|
||
yield break;
|
||
}
|
||
|
||
jsonData = File.ReadAllText(saveFilePath);
|
||
#endif
|
||
|
||
if (string.IsNullOrEmpty(jsonData))
|
||
{
|
||
if (debugMode) Debug.Log("WireDataPersistence: 没有找到连线数据");
|
||
yield break;
|
||
}
|
||
|
||
// 处理加载的数据
|
||
yield return StartCoroutine(ProcessLoadedData(jsonData));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从StreamingAssets加载数据
|
||
/// </summary>
|
||
private IEnumerator LoadFromStreamingAssets(string fileName, System.Action<string> onComplete)
|
||
{
|
||
string filePath = Path.Combine(Application.streamingAssetsPath, fileName);
|
||
UnityWebRequest webRequest = UnityWebRequest.Get(filePath);
|
||
yield return webRequest.SendWebRequest();
|
||
|
||
if (webRequest.result == UnityWebRequest.Result.Success)
|
||
{
|
||
onComplete(webRequest.downloadHandler.text);
|
||
}
|
||
else
|
||
{
|
||
onComplete("");
|
||
if (debugMode) Debug.Log("WireDataPersistence: 没有找到连线数据文件");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理加载的数据
|
||
/// </summary>
|
||
private IEnumerator ProcessLoadedData(string jsonData)
|
||
{
|
||
try
|
||
{
|
||
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}");
|
||
|
||
// 显示接口头样式统计
|
||
var startStyleGroups = data.wires.GroupBy(w => w.startInterfaceStyleName);
|
||
var endStyleGroups = data.wires.GroupBy(w => w.endInterfaceStyleName);
|
||
|
||
Debug.Log("=== 要加载的起点接口头样式 ===");
|
||
foreach (var group in startStyleGroups)
|
||
{
|
||
Debug.Log($"起点样式 '{group.Key}': {group.Count()} 个");
|
||
}
|
||
|
||
Debug.Log("=== 要加载的终点接口头样式 ===");
|
||
foreach (var group in endStyleGroups)
|
||
{
|
||
Debug.Log($"终点样式 '{group.Key}': {group.Count()} 个");
|
||
}
|
||
}
|
||
|
||
// 如果 wires 为空但 wireCount > 0,说明数据有问题
|
||
if (data.wires.Count == 0 && data.wireCount > 0)
|
||
{
|
||
Debug.LogError($"数据不一致: wireCount = {data.wireCount}, 但 wires 数组为空");
|
||
yield break;
|
||
}
|
||
|
||
// 调用连线系统的清除方法
|
||
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++;
|
||
}
|
||
// 每重建10条连线就等待一帧,避免卡顿
|
||
//if (reconstructedCount % 10 == 0)
|
||
//{
|
||
// yield return null;
|
||
//}
|
||
}
|
||
|
||
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>
|
||
/// 保持向后兼容的LoadWireData方法
|
||
/// </summary>
|
||
public void LoadWireData()
|
||
{
|
||
StartCoroutine(LoadWireDataCoroutine());
|
||
}
|
||
|
||
/// <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}, 起点样式: {wireData.startInterfaceStyleName}, 终点样式: {wireData.endInterfaceStyleName})");
|
||
|
||
// 查找接口物体
|
||
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}");
|
||
Debug.Log($"起点接口头样式: {wireData.startInterfaceStyleName}");
|
||
Debug.Log($"终点接口头样式: {wireData.endInterfaceStyleName}");
|
||
}
|
||
|
||
// 根据连线类型重建
|
||
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);
|
||
|
||
// 创建接口头样式
|
||
CreateInterfaceHeads(wireObject, wireData, startInterface, endInterface);
|
||
|
||
// 添加到连线系统
|
||
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}");
|
||
Debug.Log($"接口头样式 - 起点: {wireData.startInterfaceStyleName}, 终点: {wireData.endInterfaceStyleName}");
|
||
|
||
// 验证 CylinderWireData 字段是否设置正确
|
||
ValidateCylinderWireData(cylinderData);
|
||
}
|
||
return true;
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError($"重建圆柱体连线失败: {e.Message}");
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建接口头样式
|
||
/// </summary>
|
||
private void CreateInterfaceHeads(GameObject wireObject, SerializableWireConnectionData wireData, GameObject startInterface, GameObject endInterface)
|
||
{
|
||
try
|
||
{
|
||
// 创建起点接口头
|
||
if (!string.IsNullOrEmpty(wireData.startInterfaceStyleName) && startInterface != null)
|
||
{
|
||
GameObject startHeadPrefab = GetInterfaceHeadPrefab(wireData.startInterfaceStyleName);
|
||
if (startHeadPrefab != null)
|
||
{
|
||
GameObject startHead = Instantiate(startHeadPrefab);
|
||
startHead.name = $"InterfaceHead_Start_{wireData.startInterfaceStyleName}";
|
||
startHead.transform.SetParent(wireObject.transform);
|
||
|
||
// 设置接口头位置到起点接口位置
|
||
startHead.transform.position = startInterface.transform.position;
|
||
startHead.transform.rotation = startInterface.transform.rotation;
|
||
|
||
if (debugMode) Debug.Log($"创建起点接口头: {wireData.startInterfaceStyleName} 在 {startInterface.name}");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"找不到起点接口头预制体: {wireData.startInterfaceStyleName}");
|
||
}
|
||
}
|
||
|
||
// 创建终点接口头
|
||
if (!string.IsNullOrEmpty(wireData.endInterfaceStyleName) && endInterface != null)
|
||
{
|
||
GameObject endHeadPrefab = GetInterfaceHeadPrefab(wireData.endInterfaceStyleName);
|
||
if (endHeadPrefab != null)
|
||
{
|
||
GameObject endHead = Instantiate(endHeadPrefab);
|
||
endHead.name = $"InterfaceHead_End_{wireData.endInterfaceStyleName}";
|
||
endHead.transform.SetParent(wireObject.transform);
|
||
|
||
// 设置接口头位置到终点接口位置
|
||
endHead.transform.position = endInterface.transform.position;
|
||
endHead.transform.rotation = endInterface.transform.rotation;
|
||
|
||
if (debugMode) Debug.Log($"创建终点接口头: {wireData.endInterfaceStyleName} 在 {endInterface.name}");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"找不到终点接口头预制体: {wireData.endInterfaceStyleName}");
|
||
}
|
||
}
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
Debug.LogError($"创建接口头失败: {e.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据样式名称获取接口头预制体
|
||
/// </summary>
|
||
private GameObject GetInterfaceHeadPrefab(string styleName)
|
||
{
|
||
if (string.IsNullOrEmpty(styleName)) return null;
|
||
|
||
foreach (GameObject prefab in interfaceStylePrefabs)
|
||
{
|
||
if (prefab != null && prefab.name == styleName)
|
||
{
|
||
return prefab;
|
||
}
|
||
}
|
||
|
||
// 如果找不到指定名称的预制体,尝试使用默认样式
|
||
foreach (GameObject prefab in interfaceStylePrefabs)
|
||
{
|
||
if (prefab != null && prefab.name == defaultInterfaceStyleName)
|
||
{
|
||
return prefab;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <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;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 查找接口头样式并保存
|
||
foreach (Transform child in wireObject.transform)
|
||
{
|
||
if (child.name.StartsWith("InterfaceHead_Start"))
|
||
{
|
||
// 从接口头名称中提取样式名称
|
||
string headName = child.name;
|
||
if (headName.Contains("_"))
|
||
{
|
||
string[] parts = headName.Split('_');
|
||
if (parts.Length >= 3)
|
||
{
|
||
connectionData.startInterfaceStyleName = parts[2];
|
||
if (debugMode) Debug.Log($"保存起点接口头样式: {connectionData.startInterfaceStyleName}");
|
||
}
|
||
}
|
||
}
|
||
else if (child.name.StartsWith("InterfaceHead_End"))
|
||
{
|
||
// 从接口头名称中提取样式名称
|
||
string headName = child.name;
|
||
if (headName.Contains("_"))
|
||
{
|
||
string[] parts = headName.Split('_');
|
||
if (parts.Length >= 3)
|
||
{
|
||
connectionData.endInterfaceStyleName = parts[2];
|
||
if (debugMode) Debug.Log($"保存终点接口头样式: {connectionData.endInterfaceStyleName}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (debugMode)
|
||
{
|
||
Debug.Log($"从 CylinderWireData 组件获取连线数据: {connectionData.wireName}");
|
||
Debug.Log($"起点: {connectionData.startPoint}, 终点: {connectionData.endPoint}");
|
||
Debug.Log($"起点接口: {connectionData.startInterfaceName}, 终点接口: {connectionData.endInterfaceName}");
|
||
Debug.Log($"连线颜色: {connectionData.hasCustomColor}");
|
||
Debug.Log($"接口头样式 - 起点: {connectionData.startInterfaceStyleName}, 终点: {connectionData.endInterfaceStyleName}");
|
||
}
|
||
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;
|
||
}
|
||
}
|
||
|
||
// 查找接口头样式并保存
|
||
foreach (Transform child in wireObject.transform)
|
||
{
|
||
if (child.name.StartsWith("InterfaceHead_Start"))
|
||
{
|
||
string headName = child.name;
|
||
if (headName.Contains("_"))
|
||
{
|
||
string[] parts = headName.Split('_');
|
||
if (parts.Length >= 3)
|
||
{
|
||
connectionData.startInterfaceStyleName = parts[2];
|
||
}
|
||
}
|
||
}
|
||
else if (child.name.StartsWith("InterfaceHead_End"))
|
||
{
|
||
string headName = child.name;
|
||
if (headName.Contains("_"))
|
||
{
|
||
string[] parts = headName.Split('_');
|
||
if (parts.Length >= 3)
|
||
{
|
||
connectionData.endInterfaceStyleName = parts[2];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
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()
|
||
{
|
||
StartCoroutine(LoadWireDataCoroutine());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清除所有保存的数据
|
||
/// </summary>
|
||
public void ClearSavedData()
|
||
{
|
||
#if UNITY_WEBGL
|
||
// WebGL中使用PlayerPrefs
|
||
if (PlayerPrefs.HasKey("WireData"))
|
||
{
|
||
PlayerPrefs.DeleteKey("WireData");
|
||
PlayerPrefs.Save();
|
||
if (debugMode) Debug.Log("WireDataPersistence: 已清除PlayerPrefs中的连线数据");
|
||
}
|
||
#else
|
||
if (File.Exists(saveFilePath))
|
||
{
|
||
File.Delete(saveFilePath);
|
||
if (debugMode) Debug.Log("WireDataPersistence: 已清除保存的数据文件");
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取保存信息
|
||
/// </summary>
|
||
public string GetSaveInfo()
|
||
{
|
||
#if UNITY_WEBGL
|
||
if (PlayerPrefs.HasKey("WireData"))
|
||
{
|
||
try
|
||
{
|
||
string jsonData = PlayerPrefs.GetString("WireData");
|
||
SerializableWireData data = JsonUtility.FromJson<SerializableWireData>(jsonData);
|
||
int coloredWires = data.wires.Count(w => w.hasCustomColor);
|
||
|
||
// 统计接口头样式
|
||
var startStyleGroups = data.wires.GroupBy(w => w.startInterfaceStyleName);
|
||
var endStyleGroups = data.wires.GroupBy(w => w.endInterfaceStyleName);
|
||
|
||
string styleInfo = "";
|
||
foreach (var group in startStyleGroups)
|
||
{
|
||
if (!string.IsNullOrEmpty(group.Key))
|
||
styleInfo += $", 起点{group.Key}:{group.Count()}";
|
||
}
|
||
foreach (var group in endStyleGroups)
|
||
{
|
||
if (!string.IsNullOrEmpty(group.Key))
|
||
styleInfo += $", 终点{group.Key}:{group.Count()}";
|
||
}
|
||
|
||
return $"WireDataPersistence: 已保存 {data.wires.Count} 条连线 ({coloredWires} 条有颜色{styleInfo}), 文件大小: {jsonData.Length} 字符, 存储: PlayerPrefs";
|
||
}
|
||
catch
|
||
{
|
||
return "WireDataPersistence: PlayerPrefs中存在数据但读取失败";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return "WireDataPersistence: PlayerPrefs中暂无保存数据";
|
||
}
|
||
#else
|
||
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);
|
||
|
||
// 统计接口头样式
|
||
var startStyleGroups = data.wires.GroupBy(w => w.startInterfaceStyleName);
|
||
var endStyleGroups = data.wires.GroupBy(w => w.endInterfaceStyleName);
|
||
|
||
string styleInfo = "";
|
||
foreach (var group in startStyleGroups)
|
||
{
|
||
if (!string.IsNullOrEmpty(group.Key))
|
||
styleInfo += $", 起点{group.Key}:{group.Count()}";
|
||
}
|
||
foreach (var group in endStyleGroups)
|
||
{
|
||
if (!string.IsNullOrEmpty(group.Key))
|
||
styleInfo += $", 终点{group.Key}:{group.Count()}";
|
||
}
|
||
|
||
return $"WireDataPersistence: 已保存 {data.wires.Count} 条连线 ({coloredWires} 条有颜色{styleInfo}), 文件大小: {fileInfo.Length} 字节, 路径: {saveFilePath}";
|
||
}
|
||
catch
|
||
{
|
||
return $"WireDataPersistence: 文件存在但读取失败, 大小: {fileInfo.Length} 字节";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return "WireDataPersistence: 暂无保存数据";
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查是否有保存的数据
|
||
/// </summary>
|
||
public bool HasSavedData()
|
||
{
|
||
#if UNITY_WEBGL
|
||
return PlayerPrefs.HasKey("WireData");
|
||
#else
|
||
return File.Exists(saveFilePath);
|
||
#endif
|
||
}
|
||
|
||
/// <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;
|
||
|
||
// 统计接口头样式
|
||
Dictionary<string, int> startInterfaceStyles = new Dictionary<string, int>();
|
||
Dictionary<string, int> endInterfaceStyles = new Dictionary<string, int>();
|
||
|
||
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++;
|
||
}
|
||
}
|
||
|
||
// 统计接口头样式
|
||
foreach (Transform child in wire.transform)
|
||
{
|
||
if (child.name.StartsWith("InterfaceHead_Start"))
|
||
{
|
||
string styleName = ExtractStyleNameFromHead(child.name);
|
||
if (!string.IsNullOrEmpty(styleName))
|
||
{
|
||
if (startInterfaceStyles.ContainsKey(styleName))
|
||
startInterfaceStyles[styleName]++;
|
||
else
|
||
startInterfaceStyles[styleName] = 1;
|
||
}
|
||
}
|
||
else if (child.name.StartsWith("InterfaceHead_End"))
|
||
{
|
||
string styleName = ExtractStyleNameFromHead(child.name);
|
||
if (!string.IsNullOrEmpty(styleName))
|
||
{
|
||
if (endInterfaceStyles.ContainsKey(styleName))
|
||
endInterfaceStyles[styleName]++;
|
||
else
|
||
endInterfaceStyles[styleName] = 1;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
string styleStats = "";
|
||
foreach (var kvp in startInterfaceStyles)
|
||
{
|
||
styleStats += $", 起点{kvp.Key}:{kvp.Value}";
|
||
}
|
||
foreach (var kvp in endInterfaceStyles)
|
||
{
|
||
styleStats += $", 终点{kvp.Key}:{kvp.Value}";
|
||
}
|
||
|
||
return $"当前场景中有 {allWires?.Count ?? 0} 条连线 (圆柱体: {cylinderCount}, LineRenderer: {lineRendererCount}, 未知: {unknownCount}, 有颜色: {coloredWires}{styleStats})";
|
||
}
|
||
catch (System.Exception e)
|
||
{
|
||
return $"获取统计信息失败: {e.Message}";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从接口头名称中提取样式名称
|
||
/// </summary>
|
||
private string ExtractStyleNameFromHead(string headName)
|
||
{
|
||
if (string.IsNullOrEmpty(headName)) return "";
|
||
|
||
if (headName.Contains("_"))
|
||
{
|
||
string[] parts = headName.Split('_');
|
||
if (parts.Length >= 3)
|
||
{
|
||
return parts[2];
|
||
}
|
||
}
|
||
return "";
|
||
}
|
||
|
||
/// <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();
|
||
}
|
||
} |