修复内容:

PlayerMovement:新增 _facingLocked 字段 + LockFacing(bool) 方法;UpdateFacing() 锁定时直接返回
WallSlideState:OnStateEnter 调用 LockFacing(true) + FlipFacing(_wallDir);OnStateExit 调用 LockFacing(false) 解锁
WallJumpState:OnStateEnter 保险性再调一次 LockFacing(false);WallJumpAway/Toward 同步写入 _inputVelocityX,确保解锁后 UpdateFacing 朝向正确(背墙跳 = 离墙方向,对墙跳 = 朝墙方向)
This commit is contained in:
2026-05-22 10:48:52 +08:00
parent 285ac46e31
commit 68d4c699ae
15 changed files with 235 additions and 418 deletions

View File

@@ -2,6 +2,7 @@
using System;
using Animancer;
using BaseGames.Feedback;
using BaseGames.Input;
using BaseGames.World;
using UnityEngine;
@@ -38,6 +39,9 @@ namespace BaseGames.Puzzle
[Header("持久化SO 注入,非 Instance 单例)")]
[SerializeField] private WorldStateRegistry _worldState;
[Header("Hold 模式输入SwitchTriggerMode.Hold 时必填)")]
[SerializeField] private InputReaderSO _inputReader;
private bool _isActive;
public bool IsActive => _isActive;
@@ -59,16 +63,41 @@ namespace BaseGames.Puzzle
// ── IInteractable ────────────────────────────────────────────────────
public string InteractPrompt => _mode == SwitchTriggerMode.Hold ? "按住交互" : "交互";
public bool CanInteract => true;
/// <summary>
/// 压板模式不需要交互提示物理触发InteractOnce 已激活后隐藏提示。
/// </summary>
public bool CanInteract => _mode switch
{
SwitchTriggerMode.InteractOnce => !_isActive,
SwitchTriggerMode.InteractToggle => true,
SwitchTriggerMode.Hold => true,
SwitchTriggerMode.Pressure => false,
_ => false,
};
public void Interact(Transform player)
{
// Hold 模式通过 OnPlayerEnterRange 订阅输入事件处理,此处不响应
if (_mode == SwitchTriggerMode.Hold) return;
if (_mode == SwitchTriggerMode.InteractOnce && _isActive) return;
SetState(!_isActive);
}
public void OnPlayerEnterRange(Transform player) { }
public void OnPlayerExitRange() { }
public void OnPlayerEnterRange(Transform player)
{
if (_mode != SwitchTriggerMode.Hold || _inputReader == null) return;
_inputReader.InteractEvent += OnHoldStarted;
_inputReader.InteractCancelledEvent += OnHoldCancelled;
}
public void OnPlayerExitRange()
{
UnsubscribeHold();
// 玩家离开范围时停用 Hold 开关
if (_mode == SwitchTriggerMode.Hold && _isActive)
SetState(false);
}
// ── ISwitchable ──────────────────────────────────────────────────────
public void ForceState(bool active) => SetState(active);
@@ -106,5 +135,19 @@ namespace BaseGames.Puzzle
else _worldState?.ClearFlag("switch_" + _switchId);
}
}
// ── Hold 模式辅助 ──────────────────────────────────────────────────────
private void OnHoldStarted() => SetState(true);
private void OnHoldCancelled() => SetState(false);
private void UnsubscribeHold()
{
if (_inputReader == null) return;
_inputReader.InteractEvent -= OnHoldStarted;
_inputReader.InteractCancelledEvent -= OnHoldCancelled;
}
private void OnDestroy() => UnsubscribeHold();
}
}