Merge branch 'main' of http://59.18.227.134:30008/dal4segno/Northbound
This commit is contained in:
@@ -34,7 +34,6 @@ namespace Northbound
|
|||||||
private int currentRotation = 0; // 0-3
|
private int currentRotation = 0; // 0-3
|
||||||
private Material[] originalMaterials;
|
private Material[] originalMaterials;
|
||||||
private Renderer[] previewRenderers;
|
private Renderer[] previewRenderers;
|
||||||
private PlayerInputActions _inputActions;
|
|
||||||
|
|
||||||
// 드래그 건설 관련
|
// 드래그 건설 관련
|
||||||
private bool isDragging = false;
|
private bool isDragging = false;
|
||||||
@@ -53,35 +52,35 @@ namespace Northbound
|
|||||||
{
|
{
|
||||||
_playerController = GetComponent<NetworkPlayerController>();
|
_playerController = GetComponent<NetworkPlayerController>();
|
||||||
|
|
||||||
// 지연 초기화 - 다음 프레임에 체크
|
if (_playerController != null)
|
||||||
StartCoroutine(InitializeAfterOwnerSet());
|
{
|
||||||
|
_playerController.OnInputInitialized += TryInitializeInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 이미 로컬 플레이어면 입력 초기화 시도
|
||||||
|
TryInitializeInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
private System.Collections.IEnumerator InitializeAfterOwnerSet()
|
private void Start()
|
||||||
{
|
{
|
||||||
// _ownerPlayerId가 설정될 때까지 대기 (최대 1초)
|
// Start에서 다시 한번 확인 (이벤트 타이밍 문제 해결)
|
||||||
float timeout = 1f;
|
TryInitializeInput();
|
||||||
while (_playerController != null && _playerController.OwnerPlayerId == ulong.MaxValue && timeout > 0)
|
}
|
||||||
{
|
|
||||||
yield return null;
|
|
||||||
timeout -= Time.deltaTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 로컬 플레이어인지 확인
|
private void TryInitializeInput()
|
||||||
if (_playerController == null || !_playerController.IsLocalPlayer)
|
{
|
||||||
{
|
if (_isInitialized) return; // 이미 초기화됨
|
||||||
yield break;
|
if (_playerController == null || !_playerController.IsLocalPlayer) return;
|
||||||
}
|
if (_playerController.InputActions == null) return;
|
||||||
|
|
||||||
_isInitialized = true;
|
_isInitialized = true;
|
||||||
|
|
||||||
_inputActions = new PlayerInputActions();
|
var inputActions = _playerController.InputActions;
|
||||||
_inputActions.Player.ToggleBuildMode.performed += OnToggleBuildMode;
|
inputActions.Player.ToggleBuildMode.performed += OnToggleBuildMode;
|
||||||
_inputActions.Player.Rotate.performed += OnRotate;
|
inputActions.Player.Rotate.performed += OnRotate;
|
||||||
_inputActions.Player.Build.performed += OnBuildPressed;
|
inputActions.Player.Build.performed += OnBuildPressed;
|
||||||
_inputActions.Player.Build.canceled += OnBuildReleased;
|
inputActions.Player.Build.canceled += OnBuildReleased;
|
||||||
_inputActions.Player.Cancel.performed += OnCancel;
|
inputActions.Player.Cancel.performed += OnCancel;
|
||||||
_inputActions.Enable();
|
|
||||||
|
|
||||||
// Create default materials if not assigned
|
// Create default materials if not assigned
|
||||||
if (validMaterial == null)
|
if (validMaterial == null)
|
||||||
@@ -144,15 +143,19 @@ namespace Northbound
|
|||||||
|
|
||||||
public override void OnNetworkDespawn()
|
public override void OnNetworkDespawn()
|
||||||
{
|
{
|
||||||
if (_isInitialized && _inputActions != null)
|
if (_playerController != null)
|
||||||
{
|
{
|
||||||
_inputActions.Player.ToggleBuildMode.performed -= OnToggleBuildMode;
|
_playerController.OnInputInitialized -= TryInitializeInput;
|
||||||
_inputActions.Player.Rotate.performed -= OnRotate;
|
|
||||||
_inputActions.Player.Build.performed -= OnBuildPressed;
|
if (_isInitialized && _playerController.InputActions != null)
|
||||||
_inputActions.Player.Build.canceled -= OnBuildReleased;
|
{
|
||||||
_inputActions.Player.Cancel.performed -= OnCancel;
|
var inputActions = _playerController.InputActions;
|
||||||
_inputActions.Disable();
|
inputActions.Player.ToggleBuildMode.performed -= OnToggleBuildMode;
|
||||||
_inputActions.Dispose();
|
inputActions.Player.Rotate.performed -= OnRotate;
|
||||||
|
inputActions.Player.Build.performed -= OnBuildPressed;
|
||||||
|
inputActions.Player.Build.canceled -= OnBuildReleased;
|
||||||
|
inputActions.Player.Cancel.performed -= OnCancel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearDragPreviews();
|
ClearDragPreviews();
|
||||||
|
|||||||
@@ -65,9 +65,15 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
|
|||||||
|
|
||||||
public ulong OwnerPlayerId => _ownerPlayerId.Value;
|
public ulong OwnerPlayerId => _ownerPlayerId.Value;
|
||||||
|
|
||||||
|
// 중앙 집중식 입력 관리 - 다른 컴포넌트에서 참조
|
||||||
|
public PlayerInputActions InputActions => _inputActions;
|
||||||
|
|
||||||
// 소유자 변경 이벤트
|
// 소유자 변경 이벤트
|
||||||
public event Action<ulong> OnOwnerChanged;
|
public event Action<ulong> OnOwnerChanged;
|
||||||
|
|
||||||
|
// 입력 시스템 초기화 완료 이벤트
|
||||||
|
public event Action OnInputInitialized;
|
||||||
|
|
||||||
void Awake()
|
void Awake()
|
||||||
{
|
{
|
||||||
_controller = GetComponent<CharacterController>();
|
_controller = GetComponent<CharacterController>();
|
||||||
@@ -141,6 +147,9 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
|
|||||||
|
|
||||||
_inputActions = new PlayerInputActions();
|
_inputActions = new PlayerInputActions();
|
||||||
_inputActions.Enable();
|
_inputActions.Enable();
|
||||||
|
|
||||||
|
// 입력 초기화 완료 이벤트 발생
|
||||||
|
OnInputInitialized?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -152,6 +161,28 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
|
|||||||
_ownerPlayerId.Value = ownerPlayerId;
|
_ownerPlayerId.Value = ownerPlayerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 입력 강제 복구 (입력이 멈췄을 때 호출)
|
||||||
|
/// </summary>
|
||||||
|
public void ForceRecoverInput()
|
||||||
|
{
|
||||||
|
if (!IsLocalPlayer) return;
|
||||||
|
|
||||||
|
// InputActions가 없으면 초기화 시도
|
||||||
|
if (_inputActions == null)
|
||||||
|
{
|
||||||
|
TryInitializeLocalPlayer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// InputActions가 있지만 비활성화되어 있으면 활성화
|
||||||
|
if (!_inputActions.Player.enabled && _currentHealth.Value > 0)
|
||||||
|
{
|
||||||
|
_inputActions.Enable();
|
||||||
|
Debug.Log("[NetworkPlayerController] 입력 강제 복구 완료");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnNetworkDespawn()
|
public override void OnNetworkDespawn()
|
||||||
{
|
{
|
||||||
_currentHealth.OnValueChanged -= OnHealthChanged;
|
_currentHealth.OnValueChanged -= OnHealthChanged;
|
||||||
@@ -173,6 +204,10 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
|
|||||||
// 서버 측 이동 입력 저장
|
// 서버 측 이동 입력 저장
|
||||||
private Vector2 _serverMoveInput;
|
private Vector2 _serverMoveInput;
|
||||||
|
|
||||||
|
// 입력 복구 체크
|
||||||
|
private float _inputRecoveryCheckInterval = 1f; // 1초마다 체크
|
||||||
|
private float _inputRecoveryCheckTimer;
|
||||||
|
|
||||||
void Update()
|
void Update()
|
||||||
{
|
{
|
||||||
// 서버에서 체력 자연 회복 처리
|
// 서버에서 체력 자연 회복 처리
|
||||||
@@ -184,8 +219,24 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
|
|||||||
// 로컬 플레이어만 입력 처리
|
// 로컬 플레이어만 입력 처리
|
||||||
if (!IsLocalPlayer) return;
|
if (!IsLocalPlayer) return;
|
||||||
|
|
||||||
// 입력 시스템이 초기화되지 않았으면 스킵
|
// 입력 시스템이 초기화되지 않았으면 초기화 시도
|
||||||
if (_inputActions == null) return;
|
if (_inputActions == null)
|
||||||
|
{
|
||||||
|
TryInitializeLocalPlayer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 주기적으로 입력 상태 확인 및 자동 복구 (살아있는데 입력이 비활성화된 경우)
|
||||||
|
_inputRecoveryCheckTimer += Time.deltaTime;
|
||||||
|
if (_inputRecoveryCheckTimer >= _inputRecoveryCheckInterval)
|
||||||
|
{
|
||||||
|
_inputRecoveryCheckTimer = 0f;
|
||||||
|
if (_currentHealth.Value > 0 && !_inputActions.Player.enabled)
|
||||||
|
{
|
||||||
|
Debug.LogWarning("[NetworkPlayerController] 입력이 비활성화되어 있음 - 자동 복구");
|
||||||
|
_inputActions.Enable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 죽었으면 이동 불가
|
// 죽었으면 이동 불가
|
||||||
if (_currentHealth.Value <= 0) return;
|
if (_currentHealth.Value <= 0) return;
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ namespace Northbound
|
|||||||
[Header("Animation")]
|
[Header("Animation")]
|
||||||
public bool playAnimations = true;
|
public bool playAnimations = true;
|
||||||
|
|
||||||
private PlayerInputActions _inputActions;
|
|
||||||
private Dictionary<string, IAction> _actions = new Dictionary<string, IAction>();
|
private Dictionary<string, IAction> _actions = new Dictionary<string, IAction>();
|
||||||
private Animator _animator;
|
private Animator _animator;
|
||||||
private NetworkAnimator _networkAnimator;
|
private NetworkAnimator _networkAnimator;
|
||||||
private NetworkPlayerController _networkPlayerController;
|
private NetworkPlayerController _networkPlayerController;
|
||||||
|
private bool _isInputInitialized = false;
|
||||||
|
|
||||||
// 로컬 플레이어인지 확인
|
// 로컬 플레이어인지 확인
|
||||||
private bool IsLocalPlayer => _networkPlayerController != null && _networkPlayerController.IsLocalPlayer;
|
private bool IsLocalPlayer => _networkPlayerController != null && _networkPlayerController.IsLocalPlayer;
|
||||||
@@ -49,12 +49,19 @@ namespace Northbound
|
|||||||
if (_networkPlayerController != null)
|
if (_networkPlayerController != null)
|
||||||
{
|
{
|
||||||
_networkPlayerController.OnOwnerChanged += OnOwnerPlayerIdChanged;
|
_networkPlayerController.OnOwnerChanged += OnOwnerPlayerIdChanged;
|
||||||
|
_networkPlayerController.OnInputInitialized += TryInitializeInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 이미 로컬 플레이어면 입력 초기화
|
// 이미 로컬 플레이어면 입력 초기화
|
||||||
TryInitializeInput();
|
TryInitializeInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
// Start에서 다시 한번 확인 (이벤트 타이밍 문제 해결)
|
||||||
|
TryInitializeInput();
|
||||||
|
}
|
||||||
|
|
||||||
private void OnOwnerPlayerIdChanged(ulong newOwnerId)
|
private void OnOwnerPlayerIdChanged(ulong newOwnerId)
|
||||||
{
|
{
|
||||||
TryInitializeInput();
|
TryInitializeInput();
|
||||||
@@ -63,11 +70,11 @@ namespace Northbound
|
|||||||
private void TryInitializeInput()
|
private void TryInitializeInput()
|
||||||
{
|
{
|
||||||
if (!IsLocalPlayer) return;
|
if (!IsLocalPlayer) return;
|
||||||
if (_inputActions != null) return;
|
if (_isInputInitialized) return; // 이미 초기화됨
|
||||||
|
if (_networkPlayerController.InputActions == null) return; // 아직 InputActions가 없음
|
||||||
|
|
||||||
_inputActions = new PlayerInputActions();
|
_isInputInitialized = true;
|
||||||
_inputActions.Player.Attack.performed += OnAttack;
|
_networkPlayerController.InputActions.Player.Attack.performed += OnAttack;
|
||||||
_inputActions.Enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnNetworkDespawn()
|
public override void OnNetworkDespawn()
|
||||||
@@ -75,13 +82,13 @@ namespace Northbound
|
|||||||
if (_networkPlayerController != null)
|
if (_networkPlayerController != null)
|
||||||
{
|
{
|
||||||
_networkPlayerController.OnOwnerChanged -= OnOwnerPlayerIdChanged;
|
_networkPlayerController.OnOwnerChanged -= OnOwnerPlayerIdChanged;
|
||||||
}
|
_networkPlayerController.OnInputInitialized -= TryInitializeInput;
|
||||||
|
|
||||||
if (_inputActions != null)
|
// 입력 이벤트 해제
|
||||||
{
|
if (_networkPlayerController.InputActions != null)
|
||||||
_inputActions.Player.Attack.performed -= OnAttack;
|
{
|
||||||
_inputActions.Disable();
|
_networkPlayerController.InputActions.Player.Attack.performed -= OnAttack;
|
||||||
_inputActions.Dispose();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,11 +133,7 @@ namespace Northbound
|
|||||||
|
|
||||||
override public void OnDestroy()
|
override public void OnDestroy()
|
||||||
{
|
{
|
||||||
if (_inputActions != null)
|
// 입력 정리는 NetworkPlayerController에서 담당
|
||||||
{
|
|
||||||
_inputActions.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
base.OnDestroy();
|
base.OnDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ namespace Northbound
|
|||||||
[Header("Worker")]
|
[Header("Worker")]
|
||||||
public Worker assignedWorker;
|
public Worker assignedWorker;
|
||||||
|
|
||||||
private PlayerInputActions _inputActions;
|
|
||||||
private IInteractable _currentInteractable;
|
private IInteractable _currentInteractable;
|
||||||
private IInteractable _unavailableInteractable;
|
private IInteractable _unavailableInteractable;
|
||||||
private Camera _mainCamera;
|
private Camera _mainCamera;
|
||||||
@@ -48,6 +47,7 @@ namespace Northbound
|
|||||||
|
|
||||||
private NetworkPlayerController _networkPlayerController;
|
private NetworkPlayerController _networkPlayerController;
|
||||||
private PlayerStats _playerStats;
|
private PlayerStats _playerStats;
|
||||||
|
private bool _isInputInitialized = false;
|
||||||
|
|
||||||
public bool IsInteracting => _isInteracting;
|
public bool IsInteracting => _isInteracting;
|
||||||
public float WorkPower => _playerStats?.GetManpower() ?? 10f;
|
public float WorkPower => _playerStats?.GetManpower() ?? 10f;
|
||||||
@@ -77,12 +77,19 @@ namespace Northbound
|
|||||||
if (_networkPlayerController != null)
|
if (_networkPlayerController != null)
|
||||||
{
|
{
|
||||||
_networkPlayerController.OnOwnerChanged += OnOwnerPlayerIdChanged;
|
_networkPlayerController.OnOwnerChanged += OnOwnerPlayerIdChanged;
|
||||||
|
_networkPlayerController.OnInputInitialized += TryInitializeInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 이미 로컬 플레이어면 입력 초기화
|
// 이미 로컬 플레이어면 입력 초기화
|
||||||
TryInitializeInput();
|
TryInitializeInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Start()
|
||||||
|
{
|
||||||
|
// Start에서 다시 한번 확인 (이벤트 타이밍 문제 해결)
|
||||||
|
TryInitializeInput();
|
||||||
|
}
|
||||||
|
|
||||||
private void OnOwnerPlayerIdChanged(ulong newOwnerId)
|
private void OnOwnerPlayerIdChanged(ulong newOwnerId)
|
||||||
{
|
{
|
||||||
TryInitializeInput();
|
TryInitializeInput();
|
||||||
@@ -91,12 +98,12 @@ namespace Northbound
|
|||||||
private void TryInitializeInput()
|
private void TryInitializeInput()
|
||||||
{
|
{
|
||||||
if (!IsLocalPlayer) return;
|
if (!IsLocalPlayer) return;
|
||||||
if (_inputActions != null) return;
|
if (_isInputInitialized) return; // 이미 초기화됨
|
||||||
|
if (_networkPlayerController.InputActions == null) return; // 아직 InputActions가 없음
|
||||||
|
|
||||||
|
_isInputInitialized = true;
|
||||||
_mainCamera = Camera.main;
|
_mainCamera = Camera.main;
|
||||||
_inputActions = new PlayerInputActions();
|
_networkPlayerController.InputActions.Player.Interact.performed += OnInteract;
|
||||||
_inputActions.Player.Interact.performed += OnInteract;
|
|
||||||
_inputActions.Enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnNetworkDespawn()
|
public override void OnNetworkDespawn()
|
||||||
@@ -104,13 +111,13 @@ namespace Northbound
|
|||||||
if (_networkPlayerController != null)
|
if (_networkPlayerController != null)
|
||||||
{
|
{
|
||||||
_networkPlayerController.OnOwnerChanged -= OnOwnerPlayerIdChanged;
|
_networkPlayerController.OnOwnerChanged -= OnOwnerPlayerIdChanged;
|
||||||
}
|
_networkPlayerController.OnInputInitialized -= TryInitializeInput;
|
||||||
|
|
||||||
if (_inputActions != null)
|
// 입력 이벤트 해제
|
||||||
{
|
if (_networkPlayerController.InputActions != null)
|
||||||
_inputActions.Player.Interact.performed -= OnInteract;
|
{
|
||||||
_inputActions.Disable();
|
_networkPlayerController.InputActions.Player.Interact.performed -= OnInteract;
|
||||||
_inputActions.Dispose();
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,10 +409,7 @@ namespace Northbound
|
|||||||
|
|
||||||
public override void OnDestroy()
|
public override void OnDestroy()
|
||||||
{
|
{
|
||||||
if (_inputActions != null)
|
// 입력 정리는 NetworkPlayerController에서 담당
|
||||||
{
|
|
||||||
_inputActions.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user