지하 생성 및 터널 구조 개선
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.InputSystem;
|
||||
using Unity.Netcode; // NGO 필수 네임스페이스
|
||||
using Unity.Netcode;
|
||||
using Unity.Netcode.Components;
|
||||
|
||||
[RequireComponent(typeof(NetworkObject))]
|
||||
public class PlayerNetworkController : NetworkBehaviour
|
||||
{
|
||||
// ... 기존 변수들 유지 ...
|
||||
[Header("Movement Settings")]
|
||||
public float moveSpeed = 5f;
|
||||
public float rotationSpeed = 10f;
|
||||
@@ -21,7 +22,7 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
[Header("Mining Settings")]
|
||||
[SerializeField] private float attackRange = 1.5f;
|
||||
[SerializeField] private int miningDamage = 25;
|
||||
[SerializeField] private LayerMask mineableLayer; // 'Mineable' 레이어 설정 필요
|
||||
[SerializeField] private LayerMask mineableLayer;
|
||||
|
||||
private CharacterController _controller;
|
||||
private PlayerInputActions _inputActions;
|
||||
@@ -34,16 +35,15 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
private bool _isGrounded;
|
||||
private bool _isHoldingInteract = false;
|
||||
|
||||
// NGO에서 Start 대신 사용하는 네트워크 초기화 메서드
|
||||
// NGO 초기화
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
// 내 캐릭터가 아니라면 입력을 활성화하지 않습니다.
|
||||
if (!IsOwner) return;
|
||||
|
||||
_inputActions = new PlayerInputActions();
|
||||
_inputActions.Player.Jump.performed += ctx => OnJump();
|
||||
_inputActions.Player.Attack.performed += ctx => OnAttackServerRpc(); // 서버에 공격 요청
|
||||
_inputActions.Player.Interact.performed += ctx => OnInteractTap();
|
||||
_inputActions.Player.Attack.performed += ctx => OnAttackServerRpc();
|
||||
_inputActions.Player.Interact.performed += ctx => OnInteractTap(); // 탭 상호작용
|
||||
|
||||
_inputActions.Player.Interact.started += ctx => _isHoldingInteract = true;
|
||||
_inputActions.Player.Interact.canceled += ctx => _isHoldingInteract = false;
|
||||
@@ -60,17 +60,16 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
|
||||
void Update()
|
||||
{
|
||||
// [중요] '나'의 캐릭터가 아니면 조종 로직을 아예 실행하지 않습니다.
|
||||
if (!IsOwner) return;
|
||||
if (_traveler != null && _traveler.IsTraveling) return;
|
||||
|
||||
HandleGravity();
|
||||
HandleMovement();
|
||||
|
||||
// 건설 가속 로직
|
||||
if (_isHoldingInteract) PerformConstructionSupport();
|
||||
}
|
||||
|
||||
// --- 이동 관련 로직 (기존 유지) ---
|
||||
private void HandleMovement()
|
||||
{
|
||||
_isGrounded = _controller.isGrounded;
|
||||
@@ -80,7 +79,6 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
_moveInput = _inputActions.Player.Move.ReadValue<Vector2>();
|
||||
Vector3 move = new Vector3(_moveInput.x, 0, _moveInput.y).normalized;
|
||||
|
||||
// 지상/공중 및 공격 중 관성 처리
|
||||
if (isAttacking) move = _isGrounded ? Vector3.zero : _currentMoveDir;
|
||||
else if (move.magnitude > 0.1f) _currentMoveDir = move;
|
||||
|
||||
@@ -93,7 +91,6 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
}
|
||||
_controller.Move(move * moveSpeed * Time.deltaTime);
|
||||
}
|
||||
|
||||
_animator.SetFloat("MoveSpeed", isAttacking && _isGrounded ? 0 : move.magnitude);
|
||||
}
|
||||
|
||||
@@ -109,49 +106,56 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
if (_isGrounded) _velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
|
||||
}
|
||||
|
||||
// 기존 OnAttackServerRpc를 수정하거나 호출되는 시점에 아래 로직 포함
|
||||
// --- 채광 로직 (기존 유지) ---
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Owner)]
|
||||
private void OnAttackServerRpc()
|
||||
{
|
||||
// 모든 유저에게 애니메이션 재생 신호 전송
|
||||
OnAttackClientRpc();
|
||||
|
||||
// [채광 판정] 서버에서 물리 연산을 통해 전방의 블록 탐색
|
||||
Collider[] hitBlocks = Physics.OverlapSphere(transform.position + transform.forward, attackRange, mineableLayer);
|
||||
|
||||
foreach (var col in hitBlocks)
|
||||
{
|
||||
MineableBlock block = col.GetComponentInParent<MineableBlock>();
|
||||
if (block != null)
|
||||
{
|
||||
// 서버가 직접 블록의 대미지 함수 호출
|
||||
block.TakeDamageRpc(miningDamage);
|
||||
}
|
||||
if (block != null) block.TakeDamageRpc(miningDamage);
|
||||
}
|
||||
}
|
||||
|
||||
[ClientRpc]
|
||||
private void OnAttackClientRpc()
|
||||
{
|
||||
_animator.SetTrigger("Attack");
|
||||
}
|
||||
private void OnAttackClientRpc() => _animator.SetTrigger("Attack");
|
||||
|
||||
private void OnInteractTap()
|
||||
{
|
||||
if (!IsOwner) return;
|
||||
_animator.SetTrigger("Interact");
|
||||
|
||||
// 1. 캐릭터 주변 반경 내의 모든 콜라이더 감지
|
||||
Collider[] colliders = Physics.OverlapSphere(transform.position, interactRange, interactableLayer);
|
||||
|
||||
IInteractable closestTarget = null;
|
||||
float minDistance = float.MaxValue;
|
||||
|
||||
foreach (var col in colliders)
|
||||
{
|
||||
IInteractable interactable = col.GetComponentInParent<IInteractable>();
|
||||
if (interactable != null)
|
||||
// 2. 방향 조건 없이 거리만 체크하여 가장 가까운 것 선택
|
||||
float dist = Vector3.Distance(transform.position, col.transform.position);
|
||||
if (dist < minDistance)
|
||||
{
|
||||
interactable.Interact(gameObject);
|
||||
break;
|
||||
IInteractable interactable = col.GetComponentInParent<IInteractable>();
|
||||
if (interactable != null)
|
||||
{
|
||||
minDistance = dist;
|
||||
closestTarget = interactable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 가장 가까운 대상이 있다면 상호작용 실행
|
||||
if (closestTarget != null)
|
||||
{
|
||||
closestTarget.Interact(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
// 건설 지원 로직 (범위 내 지속 작업이므로 OverlapSphere 유지 또는 Raycast로 변경 가능)
|
||||
private void PerformConstructionSupport()
|
||||
{
|
||||
Collider[] targets = Physics.OverlapSphere(transform.position, interactRange, constructionLayer);
|
||||
@@ -160,7 +164,6 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
ConstructionSite site = col.GetComponentInParent<ConstructionSite>();
|
||||
if (site != null)
|
||||
{
|
||||
// 건설 진행도는 서버에서 관리하는 것이 안전하므로 나중에 RPC로 전환 필요
|
||||
site.AdvanceConstruction(Time.deltaTime * buildSpeedMultiplier);
|
||||
}
|
||||
}
|
||||
@@ -168,6 +171,6 @@ public class PlayerNetworkController : NetworkBehaviour
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
if (IsOwner) _inputActions.Disable();
|
||||
if (IsOwner && _inputActions != null) _inputActions.Disable();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user