219 lines
7.5 KiB
C#
219 lines
7.5 KiB
C#
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<Plug>();
|
||
CableRef = transform.Find("Cable").GetComponent<Cable>();
|
||
CableReelRef = transform.Find("CableReel").GetComponent<CableReel>();
|
||
CableRootPos = CableReelRef.transform.Find("Cable Root Pos").transform;
|
||
PhysicCableRef = transform.Find("PhysicCable").GetComponent<PhysicCable>();
|
||
|
||
BodyModuleSystem = FixSystemCenter.SystemDic.Get<BodyModuleSystem>();
|
||
}
|
||
|
||
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()
|
||
{
|
||
// 以正下方为中心驱动线盘旋转;CableReel 内部限制为左右各 60°。
|
||
if (CableRef != null && CableReelRef != null)
|
||
{
|
||
CableReelRef.UpdateRotation(PlugRef != null ? PlugRef.transform : null, !isCableRetracted);
|
||
}
|
||
}
|
||
|
||
public void ResetPlug()
|
||
{
|
||
// 不在初始插孔里,就从当前插孔拔出来,插回初始插孔
|
||
PlugRef.PullUpSocket();
|
||
BodyModuleSystem.CloseModuleSlots(null);
|
||
PlugRef.ReturnToStartPosition();
|
||
AudioManager.Instance.PlaySfx("event:/ActionFB/mods_close");
|
||
AudioManager.Instance.PlaySfx("event:/FollowInput/plugdrop");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 寻找最接近的Module
|
||
/// </summary>
|
||
/// <param name="sourcePos">源位置</param>
|
||
/// <param name="targetModule">最近的Module</param>
|
||
/// <returns>是否能找到目标范围内的Module</returns>
|
||
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<SpriteRenderer>().sortingLayerName =
|
||
CableReelRef.GetComponent<SpriteRenderer>().sortingLayerName;
|
||
PlugRef.GetComponent<SpriteRenderer>().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<LineRenderer>().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<LineRenderer>().enabled = false;
|
||
CableRef.HideCable();
|
||
|
||
// 设置Plug位置和层级
|
||
PlugRef.transform.position = retractedPos.position;
|
||
PlugRef.transform.rotation = retractedPos.rotation;
|
||
PlugRef.GetComponent<SpriteRenderer>().sortingLayerName =
|
||
CableReelRef.GetComponent<SpriteRenderer>().sortingLayerName;
|
||
PlugRef.GetComponent<SpriteRenderer>().sortingOrder = 41;
|
||
isCableRetracted = true;
|
||
}
|
||
}
|
||
}
|