입력 시스템 개선

각자의 입력 처리 로직을 갖지 않고 NetworkPlayerController로부터 받아서 쓰도록 함
This commit is contained in:
2026-02-26 01:20:23 +09:00
parent 600f35ae8f
commit 9951aa98b2
4 changed files with 65 additions and 64 deletions

View File

@@ -34,7 +34,6 @@ namespace Northbound
private int currentRotation = 0; // 0-3
private Material[] originalMaterials;
private Renderer[] previewRenderers;
private PlayerInputActions _inputActions;
// 드래그 건설 관련
private bool isDragging = false;
@@ -53,35 +52,29 @@ namespace Northbound
{
_playerController = GetComponent<NetworkPlayerController>();
// 지연 초기화 - 다음 프레임에 체크
StartCoroutine(InitializeAfterOwnerSet());
if (_playerController != null)
{
_playerController.OnInputInitialized += TryInitializeInput;
}
// 이미 로컬 플레이어면 입력 초기화 시도
TryInitializeInput();
}
private System.Collections.IEnumerator InitializeAfterOwnerSet()
private void TryInitializeInput()
{
// _ownerPlayerId가 설정될 때까지 대기 (최대 1초)
float timeout = 1f;
while (_playerController != null && _playerController.OwnerPlayerId == ulong.MaxValue && timeout > 0)
{
yield return null;
timeout -= Time.deltaTime;
}
// 로컬 플레이어인지 확인
if (_playerController == null || !_playerController.IsLocalPlayer)
{
yield break;
}
if (_isInitialized) return; // 이미 초기화됨
if (_playerController == null || !_playerController.IsLocalPlayer) return;
if (_playerController.InputActions == null) return;
_isInitialized = true;
_inputActions = new PlayerInputActions();
_inputActions.Player.ToggleBuildMode.performed += OnToggleBuildMode;
_inputActions.Player.Rotate.performed += OnRotate;
_inputActions.Player.Build.performed += OnBuildPressed;
_inputActions.Player.Build.canceled += OnBuildReleased;
_inputActions.Player.Cancel.performed += OnCancel;
_inputActions.Enable();
var inputActions = _playerController.InputActions;
inputActions.Player.ToggleBuildMode.performed += OnToggleBuildMode;
inputActions.Player.Rotate.performed += OnRotate;
inputActions.Player.Build.performed += OnBuildPressed;
inputActions.Player.Build.canceled += OnBuildReleased;
inputActions.Player.Cancel.performed += OnCancel;
// Create default materials if not assigned
if (validMaterial == null)
@@ -144,15 +137,19 @@ namespace Northbound
public override void OnNetworkDespawn()
{
if (_isInitialized && _inputActions != null)
if (_playerController != null)
{
_inputActions.Player.ToggleBuildMode.performed -= OnToggleBuildMode;
_inputActions.Player.Rotate.performed -= OnRotate;
_inputActions.Player.Build.performed -= OnBuildPressed;
_inputActions.Player.Build.canceled -= OnBuildReleased;
_inputActions.Player.Cancel.performed -= OnCancel;
_inputActions.Disable();
_inputActions.Dispose();
_playerController.OnInputInitialized -= TryInitializeInput;
if (_isInitialized && _playerController.InputActions != null)
{
var inputActions = _playerController.InputActions;
inputActions.Player.ToggleBuildMode.performed -= OnToggleBuildMode;
inputActions.Player.Rotate.performed -= OnRotate;
inputActions.Player.Build.performed -= OnBuildPressed;
inputActions.Player.Build.canceled -= OnBuildReleased;
inputActions.Player.Cancel.performed -= OnCancel;
}
}
ClearDragPreviews();

View File

@@ -65,9 +65,15 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
public ulong OwnerPlayerId => _ownerPlayerId.Value;
// 중앙 집중식 입력 관리 - 다른 컴포넌트에서 참조
public PlayerInputActions InputActions => _inputActions;
// 소유자 변경 이벤트
public event Action<ulong> OnOwnerChanged;
// 입력 시스템 초기화 완료 이벤트
public event Action OnInputInitialized;
void Awake()
{
_controller = GetComponent<CharacterController>();
@@ -141,6 +147,9 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
_inputActions = new PlayerInputActions();
_inputActions.Enable();
// 입력 초기화 완료 이벤트 발생
OnInputInitialized?.Invoke();
}
/// <summary>

View File

@@ -17,11 +17,11 @@ namespace Northbound
[Header("Animation")]
public bool playAnimations = true;
private PlayerInputActions _inputActions;
private Dictionary<string, IAction> _actions = new Dictionary<string, IAction>();
private Animator _animator;
private NetworkAnimator _networkAnimator;
private NetworkPlayerController _networkPlayerController;
private bool _isInputInitialized = false;
// 로컬 플레이어인지 확인
private bool IsLocalPlayer => _networkPlayerController != null && _networkPlayerController.IsLocalPlayer;
@@ -49,6 +49,7 @@ namespace Northbound
if (_networkPlayerController != null)
{
_networkPlayerController.OnOwnerChanged += OnOwnerPlayerIdChanged;
_networkPlayerController.OnInputInitialized += TryInitializeInput;
}
// 이미 로컬 플레이어면 입력 초기화
@@ -63,11 +64,11 @@ namespace Northbound
private void TryInitializeInput()
{
if (!IsLocalPlayer) return;
if (_inputActions != null) return;
if (_isInputInitialized) return; // 이미 초기화됨
if (_networkPlayerController.InputActions == null) return; // 아직 InputActions가 없음
_inputActions = new PlayerInputActions();
_inputActions.Player.Attack.performed += OnAttack;
_inputActions.Enable();
_isInputInitialized = true;
_networkPlayerController.InputActions.Player.Attack.performed += OnAttack;
}
public override void OnNetworkDespawn()
@@ -75,13 +76,13 @@ namespace Northbound
if (_networkPlayerController != null)
{
_networkPlayerController.OnOwnerChanged -= OnOwnerPlayerIdChanged;
}
_networkPlayerController.OnInputInitialized -= TryInitializeInput;
if (_inputActions != null)
{
_inputActions.Player.Attack.performed -= OnAttack;
_inputActions.Disable();
_inputActions.Dispose();
// 입력 이벤트 해제
if (_networkPlayerController.InputActions != null)
{
_networkPlayerController.InputActions.Player.Attack.performed -= OnAttack;
}
}
}
@@ -126,11 +127,7 @@ namespace Northbound
override public void OnDestroy()
{
if (_inputActions != null)
{
_inputActions.Dispose();
}
// 입력 정리는 NetworkPlayerController에서 담당
base.OnDestroy();
}
}

View File

@@ -33,7 +33,6 @@ namespace Northbound
[Header("Worker")]
public Worker assignedWorker;
private PlayerInputActions _inputActions;
private IInteractable _currentInteractable;
private IInteractable _unavailableInteractable;
private Camera _mainCamera;
@@ -48,6 +47,7 @@ namespace Northbound
private NetworkPlayerController _networkPlayerController;
private PlayerStats _playerStats;
private bool _isInputInitialized = false;
public bool IsInteracting => _isInteracting;
public float WorkPower => _playerStats?.GetManpower() ?? 10f;
@@ -69,7 +69,7 @@ namespace Northbound
{
_animator = GetComponent<Animator>();
_equipmentSocket = GetComponent<EquipmentSocket>();
if (rayOrigin == null)
rayOrigin = transform;
@@ -77,6 +77,7 @@ namespace Northbound
if (_networkPlayerController != null)
{
_networkPlayerController.OnOwnerChanged += OnOwnerPlayerIdChanged;
_networkPlayerController.OnInputInitialized += TryInitializeInput;
}
// 이미 로컬 플레이어면 입력 초기화
@@ -91,12 +92,12 @@ namespace Northbound
private void TryInitializeInput()
{
if (!IsLocalPlayer) return;
if (_inputActions != null) return;
if (_isInputInitialized) return; // 이미 초기화됨
if (_networkPlayerController.InputActions == null) return; // 아직 InputActions가 없음
_isInputInitialized = true;
_mainCamera = Camera.main;
_inputActions = new PlayerInputActions();
_inputActions.Player.Interact.performed += OnInteract;
_inputActions.Enable();
_networkPlayerController.InputActions.Player.Interact.performed += OnInteract;
}
public override void OnNetworkDespawn()
@@ -104,13 +105,13 @@ namespace Northbound
if (_networkPlayerController != null)
{
_networkPlayerController.OnOwnerChanged -= OnOwnerPlayerIdChanged;
}
_networkPlayerController.OnInputInitialized -= TryInitializeInput;
if (_inputActions != null)
{
_inputActions.Player.Interact.performed -= OnInteract;
_inputActions.Disable();
_inputActions.Dispose();
// 입력 이벤트 해제
if (_networkPlayerController.InputActions != null)
{
_networkPlayerController.InputActions.Player.Interact.performed -= OnInteract;
}
}
}
@@ -402,10 +403,7 @@ namespace Northbound
public override void OnDestroy()
{
if (_inputActions != null)
{
_inputActions.Dispose();
}
// 입력 정리는 NetworkPlayerController에서 담당
}
}
}