using UnityEngine; using DG.Tweening; using AibisDream.Kit; using AibisDream.Framework; namespace AibisDream.FixSystem { public enum CableMode { None, // 都隐藏(收起状态) Visual, // 使用 Cable(拖拽时) Physic // 使用 PhysicCable(闲置时) } public class CablePanel : MonoBehaviour, IOperatorPanel { private const string CableRetractedKey = "$global.cableRetracted"; private const int SortingOrderRetracted = 41; #region 组件索引 [Header("插线组件索引")] [SerializeField] private Plug plugRef; [SerializeField] private Cable cableRef; [SerializeField] private PhysicCable physicCableRef; [SerializeField] private Transform cableRootPos; [SerializeField] private CableReel cableReelRef; [Header("灯光系统")] [SerializeField] private CablePanelLight panelLight; public Plug PlugRef => plugRef; public Cable CableRef => cableRef; public PhysicCable PhysicCableRef => physicCableRef; public Transform CableRootPos => cableRootPos; public CableReel CableReelRef => cableReelRef; public CablePanelLight PanelLight => panelLight; public BodyModuleSystem BodyModuleSystem { get; private set; } #endregion #region 系统状态 public bool isCableRetracted = true; // 线缆是否收起 [SerializeField] private Transform retractedPos; // 收起位置 private ISocket curSocket; #endregion private void Start() { InitComponentRefs(); InitSystem(); LoadCableState(); } private void OnDestroy() { plugRef.OnInsertSocket -= OnInsertSocket; plugRef.OnPullUpSocket -= OnPullUpSocket; plugRef.OnPlugPointerDown -= OnPlugPoinerDown; } private void InitComponentRefs() { BodyModuleSystem = FixSystemCenter.SystemDic.Get(); } public void InitLight(bool isLightOn) { panelLight?.Initialize(isLightOn); } private void InitSystem() { plugRef.OnInsertSocket += OnInsertSocket; plugRef.OnPullUpSocket += OnPullUpSocket; plugRef.OnPlugPointerDown += OnPlugPoinerDown; } private void LoadCableState() { // 从Prefab读取 if (isCableRetracted) { SetRetractCable(); } else { PlugRef.ReturnToStartPosition(); } // 从存储系统读取 if (!StorageSystem.Instance.TryGetValue(CableRetractedKey, out bool savedRetractedState)) return; if (savedRetractedState) { SetRetractCable(); } else { if (isCableRetracted) DropDownCable(); } } private void SaveCableState() { Debug.Log("Save cableRetractedstate" + isCableRetracted); StorageSystem.Instance.SetValue(CableRetractedKey, isCableRetracted); } private void Update() { // 获取线缆方向并更新转盘旋转 if (CableRef != null && CableReelRef != null) { CableReelRef.UpdateRotation(); } } public void ResetPlug() { // 不在初始插孔里,就从当前插孔拔出来,插回初始插孔 PlugRef.PullUpSocket(); BodyModuleSystem.CloseModuleSlots(null); PlugRef.ReturnToStartPosition(); AudioManager.Instance.PlaySfx("event:/ActionFB/mods_close"); AudioManager.Instance.PlaySfx("event:/FollowInput/plugdrop"); } // ------------------------------ 插头事件 ------------------------------ private void OnInsertSocket(ISocket socket) { var isSameSocket = curSocket == socket; curSocket = socket; CableRef.SetEndPos(socket.GetSocketPos()); AudioManager.Instance.PlaySfx("event:/FollowInput/plugin"); if (!isSameSocket && !EventSystemEx.Instance.isLocked && socket is BodyModule bodyModule) { // 插入模块时触发插入事件 EnumEventSystem.Global.Send(EventEnum.PlugIn); } } private void OnPullUpSocket() { // 修改线头位置 CableRef.SetEndPos(PlugRef.PlugRoot); curSocket?.PlugOut(); AudioManager.Instance.PlaySfx("event:/FollowInput/plugout"); // 如果是模块 if (!EventSystemEx.Instance.isLocked && curSocket is BodyModule) { EnumEventSystem.Global.Send(EventEnum.PlugOut); } curSocket = null; } private void OnPlugPoinerDown() { if (IsPlugInSocket()) PlugRef.PullUpSocket(); // 点击时切换到视觉线缆 SetCableMode(CableMode.Visual); // 打开插孔 BodyModuleSystem.OpenModuleSlots(); } // ------------------------------ 系统状态 ------------------------------ public bool IsPlugInSocket() { return curSocket != null; } // ------------------------------ 线缆操作 ------------------------------ /// /// 设置线缆显示模式 /// /// 线缆模式 /// PhysicCable跟随的目标,默认为Plug public void SetCableMode(CableMode mode, Transform followTarget = null) { switch (mode) { case CableMode.None: CableRef.HideCable(); PhysicCableRef.SetEnabled(false); PhysicCableRef.SetTarget(null); break; case CableMode.Visual: CableRef.ShowCable(); PhysicCableRef.SetEnabled(false); PhysicCableRef.SetTarget(null); break; case CableMode.Physic: CableRef.HideCable(); PhysicCableRef.SetEnabled(true); PhysicCableRef.Init(PlugRef.transform.position); PhysicCableRef.SetTarget(followTarget != null ? followTarget : PlugRef.transform); break; } } /// /// 寻找最接近的Module /// /// 源位置 /// 最近的Module /// 是否能找到目标范围内的Module public bool TryFindClosestModule(Vector3 sourcePos, out BodyModule targetModule) { var res = BodyModuleSystem.TryFindClosestModule(sourcePos, out targetModule); BodyModuleSystem.CloseModuleSlots(targetModule); return res; } public void PullUpCable() { if (isCableRetracted) return; if (IsPlugInSocket()) { PlugRef.PullUpSocket(); } BodyModuleSystem.CloseModuleSlots(null); PlugRef.transform.DOMove(retractedPos.position, 0.1f).OnComplete(() => { ApplyRetractedState(); isCableRetracted = true; SaveCableState(); }); AudioManager.Instance.PlaySfx("event:/ActionFB/mods_close"); AudioManager.Instance.PlaySfx("event:/FollowInput/plugdrop"); } public void DropDownCable() { if (!isCableRetracted) return; // 确保 Plug 已脱离 Socket(收起状态下通常已脱离,此处为防御性调用) PlugRef.PullUpSocket(); CableReelRef.ResetRotation(); PlugRef.transform.DOMove(PlugRef.GetStartPos(), 0.1f).OnComplete(() => { SetCableMode(CableMode.Physic); isCableRetracted = false; SaveCableState(); }); } /// 应用收起状态的视觉与组件设置(不含动画、不含 isCableRetracted 更新) private void ApplyRetractedState() { SetCableMode(CableMode.None); PlugRef.transform.position = retractedPos.position; PlugRef.transform.rotation = retractedPos.rotation; var plugSprite = PlugRef.GetComponent(); plugSprite.sortingLayerName = CableReelRef.GetComponent().sortingLayerName; plugSprite.sortingOrder = SortingOrderRetracted; } public void SetRetractCable() { ApplyRetractedState(); isCableRetracted = true; } #region 灯光系统 - 供外部调用 /// /// 启动系统 /// public System.Collections.IEnumerator StartSystem() { if (panelLight != null) { yield return panelLight.StartSystem(); } } /// /// 更新呼吸灯 /// public void UpdateBreathingLight(LightState state) { panelLight?.UpdateBreathingLight(state); } /// /// 更新ECG波形 /// public void UpdateECGWave(LightState state) { panelLight?.UpdateECGWave(state); } /// /// 获取当前波形类型 /// public RobotECGWave.WaveType GetCurrentWaveType() { return panelLight != null ? panelLight.GetCurrentWaveType() : RobotECGWave.WaveType.RobotECG; } /// /// 设置波形类型 /// public void SetWaveType(RobotECGWave.WaveType waveType) { panelLight?.SetWaveType(waveType); } #endregion public void Init() { } public void Open() { } public void Close() { } } }