feat: 新增 CablePanel 电缆面板组件

Made-with: Cursor
This commit is contained in:
2026-03-03 21:44:57 +08:00
parent 4744f8c6a3
commit 9d5fccf39d
2 changed files with 305 additions and 0 deletions
@@ -0,0 +1,294 @@
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 FixLightSystem fixLightSystem;
public FixLightSystem FixLightSystem => fixLightSystem;
[Header("插线组件索引")]
[SerializeField] private Plug plugRef;
[SerializeField] private Cable cableRef;
[SerializeField] private PhysicCable physicCableRef;
[SerializeField] private Transform cableRootPos;
[SerializeField] private CableReel cableReelRef;
public Plug PlugRef => plugRef;
public Cable CableRef => cableRef;
public PhysicCable PhysicCableRef => physicCableRef;
public Transform CableRootPos => cableRootPos;
public CableReel CableReelRef => cableReelRef;
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<BodyModuleSystem>();
}
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)
{
curSocket = socket;
CableRef.SetEndPos(socket.GetSocketPos());
AudioManager.Instance.PlaySfx("event:/FollowInput/plugin");
if (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 (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;
}
// ------------------------------ 线缆操作 ------------------------------
/// <summary>
/// 设置线缆显示模式
/// </summary>
/// <param name="mode">线缆模式</param>
/// <param name="followTarget">PhysicCable跟随的目标,默认为Plug</param>
public void SetCableMode(CableMode mode, Transform followTarget = null)
{
switch (mode)
{
case CableMode.None:
CableRef.HideCable();
PhysicCableRef.HideCable();
PhysicCableRef.SetTarget(null);
break;
case CableMode.Visual:
CableRef.ShowCable();
PhysicCableRef.HideCable();
PhysicCableRef.SetTarget(null);
break;
case CableMode.Physic:
CableRef.HideCable();
PhysicCableRef.ShowCable();
PhysicCableRef.Init(PlugRef.transform.position);
PhysicCableRef.SetTarget(followTarget != null ? followTarget : PlugRef.transform);
break;
}
}
/// <summary>
/// 寻找最接近的Module
/// </summary>
/// <param name="sourcePos">源位置</param>
/// <param name="targetModule">最近的Module</param>
/// <returns>是否能找到目标范围内的Module</returns>
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();
});
}
/// <summary>应用收起状态的视觉与组件设置(不含动画、不含 isCableRetracted 更新)</summary>
private void ApplyRetractedState()
{
SetCableMode(CableMode.None);
PlugRef.transform.position = retractedPos.position;
PlugRef.transform.rotation = retractedPos.rotation;
var plugSprite = PlugRef.GetComponent<SpriteRenderer>();
plugSprite.sortingLayerName = CableReelRef.GetComponent<SpriteRenderer>().sortingLayerName;
plugSprite.sortingOrder = SortingOrderRetracted;
}
public void SetRetractCable()
{
ApplyRetractedState();
isCableRetracted = true;
}
public void Init()
{
}
public void Open()
{
}
public void Close()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 870725094d1affd4bbe0ca4723fe18ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: