Files
Cielonos/Assets/Scripts/MainGame/Characters/Player/Input/PlayerInputSubcontroller.cs
SoulliesOfficial 6d7ebc5825 Passion & UI
2026-06-12 17:11:39 -04:00

438 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using Cielonos.MainGame.Inventory;
using Cielonos.MainGame.UI;
using Sirenix.OdinInspector;
using SLSUtilities.UI;
using UniRx;
using Unity.Cinemachine;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;
using UnityEngine.Serialization;
namespace Cielonos.MainGame.Characters
{
public partial class PlayerInputSubcontroller : SubcontrollerBase<Player>
{
public Player player => owner;
public PlayerInput playerInput;
public PlayerInputActions inputActions;
public PlayerOperationSubcontroller operation;
public Vector2 Move { get; private set; }
public Vector2 Look { get; private set; }
public bool JumpPressed { get; private set; }
public bool JumpHeld { get; private set; }
public bool IsMoving => Move != Vector2.zero;
public bool IsWalking { get; private set; }
public string CurrentScheme => playerInput.currentControlScheme;
[ShowInInspector]
public bool IsHoldingPrimary { get; private set; }
[ShowInInspector]
public bool IsHoldingSecondary { get; private set; }
[ShowInInspector]
public bool IsHoldingSpecialA { get; private set; }
[ShowInInspector]
public bool IsHoldingSpecialB { get; private set; }
[ShowInInspector]
public bool IsHoldingSpecialC { get; private set; }
public BoolReactiveProperty isCursorLocked;
public PlayerPreinputSubmodule preinputSubmodule;
public override void Initialize()
{
base.Initialize();
playerInput = owner.GetComponent<PlayerInput>();
inputActions = new PlayerInputActions();
inputActions.Player.Enable();
operation = owner.operationSc;
isCursorLocked = new BoolReactiveProperty(true);
isCursorLocked.Subscribe(isLocked =>
{
Cursor.lockState = isLocked ? CursorLockMode.Locked : CursorLockMode.None;
Cursor.visible = !isLocked;
Look = Vector2.zero;
Move = Vector2.zero;
// 同步禁用 Cinemachine 的自有输入控制器,防止 UI 打开时视角继续转动
var cinemachineInput = player.viewSc.freeLookCamera.GetComponent<CinemachineInputAxisController>();
cinemachineInput.enabled = isLocked;
});
player.inputSc.isCursorLocked.Value = false;
preinputSubmodule = new PlayerPreinputSubmodule(this);
InputBindingResolver.Initialize(inputActions.asset, "KeyboardMouse");
}
private void Start()
{
RegisterActionsInputs();
RegisterMainWeaponInputs();
RegisterSupportEquipmentInputs();
RegisterFunctionInputs();
SceneManager.sceneLoaded += OnSceneLoaded;
}
private void Update()
{
if (isCursorLocked.Value)
{
Look = inputActions.Player.Look.ReadValue<Vector2>();
Move = inputActions.Player.Move.ReadValue<Vector2>().normalized;
JumpPressed = inputActions.Player.Jump.WasPressedThisFrame();
JumpHeld = inputActions.Player.Jump.IsPressed();
}
}
private void OnDestroy()
{
inputActions.Disable();
inputActions.Dispose();
SceneManager.sceneLoaded -= OnSceneLoaded;
}
}
public partial class PlayerInputSubcontroller
{
private void RegisterActionsInputs()
{
inputActions.Player.Interact.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.Interact();
}
};
inputActions.Player.Dash.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
if (IsMoving)
{
Vector3 inputDirection = new Vector3(Move.x, 0, Move.y);
operation.Dash(inputDirection);
preinputSubmodule.RegisterPreinputAction(() => operation.Dash(inputDirection), 10);
}
else
{
operation.Dodge();
preinputSubmodule.RegisterPreinputAction(() => operation.Dodge(), 10);
}
}
};
inputActions.Player.LockonTarget.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.LockonTarget();
}
};
inputActions.Player.SelectLockonTarget.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
//Debug.Log("Value: " + ctx.ReadValue<float>());
operation.SelectLockonTarget(ctx.ReadValue<float>());
}
};
inputActions.Player.Walk.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
IsWalking = true;
operation.WalkPress();
}
};
inputActions.Player.Walk.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
IsWalking = false;
operation.WalkRelease();
}
};
// 交互选项导航:滚轮向上 / ↑ = -1向上滚轮向下 / ↓ = +1向下
// PassThrough + Axis 类型在松手/滚轮归零时也会触发 performedraw = 0需过滤
inputActions.Player.NavigateInteractionChoice.performed += ctx =>
{
if (isCursorLocked.Value)
{
float raw = ctx.ReadValue<float>();
if (Mathf.Approximately(raw, 0f)) return;
int delta = raw > 0f ? -1 : 1;
operation.NavigateInteractionChoice(delta);
}
};
}
private MainWeaponBase currentMainWeapon => player.inventorySc.equipmentSm.currentMainWeapon;
private void RegisterMainWeaponInputs()
{
inputActions.Player.MainWeaponPrimary.started += ctx =>
{
if (ctx.started && isCursorLocked.Value)
{
IsHoldingPrimary = true;
operation.MainWeaponPrimaryPress();
if (currentMainWeapon is { disablePrimaryPreinput: false })
{
preinputSubmodule.RegisterPreinputAction(() => operation.MainWeaponPrimaryPress(), 0);
}
}
};
inputActions.Player.MainWeaponPrimary.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
IsHoldingPrimary = false;
operation.MainWeaponPrimaryRelease();
}
};
inputActions.Player.MainWeaponSecondary.started += ctx =>
{
if (ctx.started && isCursorLocked.Value)
{
IsHoldingSecondary = true;
operation.MainWeaponSecondaryPress();
if (currentMainWeapon is { disableSecondaryPreinput: false })
{
preinputSubmodule.RegisterPreinputAction(() => operation.MainWeaponSecondaryPress(), 0);
}
}
};
inputActions.Player.MainWeaponSecondary.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
IsHoldingSecondary = false;
operation.MainWeaponSecondaryRelease();
}
};
inputActions.Player.MainWeaponSpecialA.started += ctx =>
{
if (ctx.started && isCursorLocked.Value)
{
IsHoldingSpecialA = true;
operation.MainWeaponSpecialAPress();
if (currentMainWeapon is { disableSpecialAPreinput: false })
{
preinputSubmodule.RegisterPreinputAction(() => operation.MainWeaponSpecialAPress(), 0);
}
}
};
inputActions.Player.MainWeaponSpecialA.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
IsHoldingSpecialA = false;
operation.MainWeaponSpecialARelease();
}
};
inputActions.Player.MainWeaponSpecialB.started += ctx =>
{
if (ctx.started && isCursorLocked.Value)
{
IsHoldingSpecialB = true;
operation.MainWeaponSpecialBPress();
if (currentMainWeapon is { disableSpecialBPreinput: false })
{
preinputSubmodule.RegisterPreinputAction(() => operation.MainWeaponSpecialBPress(), 0);
}
}
};
inputActions.Player.MainWeaponSpecialB.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
IsHoldingSpecialB = false;
operation.MainWeaponSpecialBRelease();
}
};
inputActions.Player.MainWeaponSpecialC.started += ctx =>
{
if (ctx.started && isCursorLocked.Value)
{
IsHoldingSpecialC = true;
operation.MainWeaponSpecialCPress();
if (currentMainWeapon is { disableSpecialCPreinput: false })
{
preinputSubmodule.RegisterPreinputAction(() => operation.MainWeaponSpecialCPress(), 0);
}
}
};
inputActions.Player.MainWeaponSpecialC.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
IsHoldingSpecialC = false;
operation.MainWeaponSpecialCRelease();
}
};
inputActions.Player.SwitchPreviousMainWeapon.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.SwitchMainWeapon(-1);
}
};
inputActions.Player.SwitchNextMainWeapon.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.SwitchMainWeapon(1);
}
};
inputActions.Player.RouletteSwitchMainWeapon.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.OpenMainWeaponRoulette();
}
};
inputActions.Player.RouletteSwitchMainWeapon.canceled += ctx =>
{
if (ctx.canceled)
{
operation.CloseMainWeaponRoulette();
}
};
}
private void RegisterSupportEquipmentInputs()
{
inputActions.Player.SupportEquipment0.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.SupportEquipment0Press();
}
};
inputActions.Player.SupportEquipment0.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
operation.SupportEquipment0Release();
}
};
inputActions.Player.SupportEquipment1.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.SupportEquipment1Press();
}
};
inputActions.Player.SupportEquipment1.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
operation.SupportEquipment1Release();
}
};
inputActions.Player.SupportEquipment2.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.SupportEquipment2Press();
}
};
inputActions.Player.SupportEquipment2.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
operation.SupportEquipment2Release();
}
};
inputActions.Player.SupportEquipment3.performed += ctx =>
{
if (ctx.performed && isCursorLocked.Value)
{
operation.SupportEquipment3Press();
}
};
inputActions.Player.SupportEquipment3.canceled += ctx =>
{
if (ctx.canceled && isCursorLocked.Value)
{
operation.SupportEquipment3Release();
}
};
}
private void RegisterFunctionInputs()
{
inputActions.Player.Inventory.performed += ctx =>
{
var inventoryPage = PlayerCanvas.MainGamePages.inventoryPage;
if(inventoryPage.IsOpen)
{
inventoryPage.Close();
}
else
{
inventoryPage.Open();
}
};
inputActions.Player.Map.performed += ctx =>
{
var mapPage = PlayerCanvas.MainGamePages.mapPage;
if(mapPage.IsOpen) mapPage.Close();
else mapPage.Open();
};
inputActions.Player.Escape.performed += ctx =>
{
// 优先关闭栈顶页面(包括 Settings 覆盖在 Pause 之上的情况)
if (UIPageManager.Instance != null && UIPageManager.Instance.HasOpenPages)
{
UIPageManager.Instance.CloseTopPage();
}
else
{
PlayerCanvas.PauseUIPage.Open();
}
};
}
}
public partial class PlayerInputSubcontroller
{
private void OnSceneLoaded(Scene a, LoadSceneMode b)
{
isCursorLocked.Value = true;
}
}
}