Merge branch 'develop' into bugfix/美术素材填充

This commit is contained in:
2026-07-22 21:55:45 +08:00
130 changed files with 1529 additions and 1334 deletions
@@ -36,6 +36,10 @@ namespace AibisDream.FixSystem
#region
public bool isCableRetracted = true; // 线缆是否收起
// 与 isCableRetracted(当前可交互状态)分开记录最后一次指令的目标,
// 防止相反方向或外部 DOKill 触发旧动画回调,把线缆恢复到错误状态。
private bool targetCableRetracted = true;
[SerializeField] private Transform retractedPos; // 收起位置
private ISocket curSocket;
@@ -86,6 +90,8 @@ namespace AibisDream.FixSystem
private void InitCableVisualFromPrefab()
{
targetCableRetracted = isCableRetracted;
if (isCableRetracted)
{
SetRetractCable();
@@ -145,6 +151,8 @@ namespace AibisDream.FixSystem
public void DropDownCableImmediate()
{
targetCableRetracted = false;
PlugRef.transform.DOKill(false);
PlugRef.PullUpSocketSilent();
CableReelRef.ResetRotation();
PlugRef.RestoreAtStartPositionImmediate();
@@ -212,14 +220,25 @@ namespace AibisDream.FixSystem
}
}
/// <summary>
/// 从插孔拔出(若已插入),放回初始可插线位:线缆放下、可拖拽,不收起。
/// </summary>
public void ResetPlug()
{
if (IsPlugInSocket())
bool wasPlugged = IsPlugInSocket();
if (wasPlugged)
{
PlugRef.PullUpSocket();
}
BodyModuleSystem.CloseModuleSlots(null);
// 已在初始可插线位且未收起:只关槽,不重复放线/音效
if (!wasPlugged && !isCableRetracted && !targetCableRetracted)
{
return;
}
DropDownCableImmediate();
AudioManager.Instance.PlaySfx("event:/ActionFB/mods_close");
@@ -315,45 +334,71 @@ namespace AibisDream.FixSystem
return BodyModuleSystem.TryFindClosestModule(sourcePos, out targetModule);
}
/// <summary>收起线缆:无论是否插在模块上,统一收到线盘位。</summary>
public void PullUpCable()
{
if (isCableRetracted) return;
if (IsPlugInSocket())
bool wasPlugged = IsPlugInSocket();
if (wasPlugged)
{
PlugRef.PullUpSocket();
}
BodyModuleSystem.CloseModuleSlots(null);
// 收线动画:绳身按纯插值收拢到收纳位(不走拖拽物理,避免其阻尼参数在极短时长内来不及收敛而甩鞭),
// 插头 DOMove 与绳收拢共用同一时长,动画结束时绳已真正收完,再切换到收起态不会有可见的切割感
// 已在收起或正在收起,且本次无需拔插:不重复收线动画/音效
if (targetCableRetracted && !wasPlugged)
{
isCableRetracted = true;
return;
}
targetCableRetracted = true;
isCableRetracted = true;
PlugRef.transform.DOKill(false);
if (physicCableRef.State == PhysicCable.CableState.Hidden)
{
ApplyRetractedState();
return;
}
suppressPlugFollow = true;
physicCableRef.CollapseTo(retractedPos.position, RetractDuration);
PlugRef.transform.DOMove(retractedPos.position, RetractDuration)
.OnComplete(() =>
{
ApplyRetractedState();
isCableRetracted = true;
});
.OnComplete(CompleteRetractIfCurrent)
.OnKill(CompleteRetractIfCurrent);
AudioManager.Instance.PlaySfx("event:/ActionFB/mods_close");
AudioManager.Instance.PlaySfx("event:/FollowInput/plugdrop");
}
private void CompleteRetractIfCurrent()
{
if (!targetCableRetracted) return;
ApplyRetractedState();
isCableRetracted = true;
}
public void DropDownCable()
{
if (!isCableRetracted) return;
// 确保 Plug 已脱离 Socket(收起状态下通常已脱离,此处为防御性调用)
if (!isCableRetracted && !targetCableRetracted) return;
targetCableRetracted = false;
PlugRef.PullUpSocket();
PlugRef.transform.DOKill(false);
CableReelRef.ResetRotation();
suppressPlugFollow = true;
PlugRef.transform.DOMove(PlugRef.GetStartPos(), 0.1f).OnComplete(() =>
{
suppressPlugFollow = false;
physicCableRef.ShowFree(true);
isCableRetracted = false;
});
PlugRef.transform.DOMove(PlugRef.GetStartPos(), 0.1f).OnComplete(CompleteDropIfCurrent)
.OnKill(CompleteDropIfCurrent);
}
private void CompleteDropIfCurrent()
{
if (targetCableRetracted) return;
suppressPlugFollow = false;
physicCableRef.ShowFree(true);
isCableRetracted = false;
}
/// <summary>应用收起状态的视觉与组件设置(不含动画、不含 isCableRetracted 更新)</summary>
@@ -362,8 +407,6 @@ namespace AibisDream.FixSystem
physicCableRef.Hide();
suppressPlugFollow = false;
// 强制收起时长可能短于拔出反馈动画(挤压 punch scale),未播完就会被打断,
// 收起完成后强制清掉,避免插头带着没播完的形变停在收纳位
PlugRef.CancelFeedbackTween();
PlugRef.transform.position = retractedPos.position;
@@ -376,8 +419,10 @@ namespace AibisDream.FixSystem
public void SetRetractCable()
{
ApplyRetractedState();
targetCableRetracted = true;
isCableRetracted = true;
PlugRef.transform.DOKill(false);
ApplyRetractedState();
}
#region -