using UnityEngine; using DG.Tweening; using AibisDream.Kit; namespace AibisDream.FixSystem { public class CableSystem : MonoBehaviour { private const string CableRetractedKey = "$global.cableRetracted"; private const float RetractResetDuration = 0.06f; private const float PullUpDuration = 0.1f; private DG.Tweening.Sequence _pullUpSequence; #region 组件索引 public Plug PlugRef { get; private set; } public Cable CableRef { get; private set; } public PhysicCable PhysicCableRef { get; private set; } public Transform CableRootPos { get; private set; } public CableReel CableReelRef { get; private set; } public BodyModuleSystem BodyModuleSystem { get; private set; } #endregion #region 系统状态 public bool isActive = true; public bool isCableRetracted = true; // 线缆是否收起 [SerializeField] private Transform retractedPos; // 收起位置 [HideInInspector] public ISocket curSocket; [HideInInspector] public BodyModule curBodyModule; #endregion private void Start() { InitComponentRefs(); InitSystem(); LoadCableState(); } private void InitComponentRefs() { PlugRef = transform.Find("Plug").GetComponent(); CableRef = transform.Find("Cable").GetComponent(); CableReelRef = transform.Find("CableReel").GetComponent(); CableRootPos = CableReelRef.transform.Find("Cable Root Pos").transform; PhysicCableRef = transform.Find("PhysicCable").GetComponent(); BodyModuleSystem = FixSystemCenter.SystemDic.Get(); } private void InitSystem() { if (isCableRetracted) { SetRetractCable(); } else { PlugRef.ReturnToStartPosition(); } } private void LoadCableState() { if (YarnVariableStorage.Instance.TryGetValue(CableRetractedKey, out bool savedRetractedState)) { if (isCableRetracted) { if (!savedRetractedState) { DropDownCable(); } } else { if (savedRetractedState) { PullUpCable(); } } } } private void SaveCableState() { Debug.Log("Save cableRetractedstate" + isCableRetracted); YarnVariableStorage.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"); } /// /// 寻找最接近的Module /// /// 源位置 /// 最近的Module /// 是否能找到目标范围内的Module public bool TryFindClosestModule(Vector3 sourcePos, out BodyModule targetModule) { return BodyModuleSystem.TryFindClosestModule(sourcePos, out targetModule); } #region 系统可用状态 public void Disable_plugInput() { isActive = false; } public void Enable_plugInput() { isActive = true; } #endregion public void PullUpCable() { if (isCableRetracted || _pullUpSequence != null) return; //禁用plug交互 Disable_plugInput(); // 强制收线不能复用 ResetPlug:ReturnToStartPosition 会启动线缆的自动回收, // 紧接着再 DOMove 会让两个流程争抢插头位置,插在插孔上时尤其像直接平移消失。 PlugRef.PullUpSocket(); BodyModuleSystem.CloseModuleSlots(null); AudioManager.Instance.PlaySfx("event:/ActionFB/mods_close"); AudioManager.Instance.PlaySfx("event:/FollowInput/plugdrop"); PlugRef.GetComponent().sortingLayerName = CableReelRef.GetComponent().sortingLayerName; PlugRef.GetComponent().sortingOrder = 41; _pullUpSequence?.Kill(); PlugRef.transform.DOKill(false); _pullUpSequence = DOTween.Sequence() // 先快速从插孔复位,消除“跨场景直线吸走”的观感。 .Append(PlugRef.transform.DOMove(PlugRef.GetStartPos(), RetractResetDuration) .SetEase(Ease.OutCubic)) // 再由线盘向上收走。 .Append(PlugRef.transform.DOMove(retractedPos.position, PullUpDuration) .SetEase(Ease.InCubic)) .Join(PlugRef.transform.DORotateQuaternion(retractedPos.rotation, PullUpDuration) .SetEase(Ease.InCubic)) .OnComplete(() => { _pullUpSequence = null; PhysicCableRef.GetComponent().enabled = false; isCableRetracted = true; SaveCableState(); }); } public void DropDownCable() { if (!isCableRetracted && _pullUpSequence == null) return; _pullUpSequence?.Kill(); _pullUpSequence = null; PlugRef.PullUpSocket(); CableReelRef.ResetRotation(); PlugRef.transform.DOMove(PlugRef.GetStartPos(), 0.1f).OnComplete(() => { // PlugRef.SwitchToPhysicCableState(); isCableRetracted = false; SaveCableState(); // 添加一个短暂的延迟来确保状态正确设置 DOVirtual.DelayedCall(0.1f, () => { Enable_plugInput(); }); }); // 只有在非收起状态时才切换到物理线缆状态 } public void SetRetractCable() { _pullUpSequence?.Kill(); _pullUpSequence = null; // 禁用物理线缆和普通线缆 PhysicCableRef.GetComponent().enabled = false; CableRef.HideCable(); // 设置Plug位置和层级 PlugRef.transform.position = retractedPos.position; PlugRef.transform.rotation = retractedPos.rotation; PlugRef.GetComponent().sortingLayerName = CableReelRef.GetComponent().sortingLayerName; PlugRef.GetComponent().sortingOrder = 41; isCableRetracted = true; } } }