Files
Northbound/Assets/Scripts/InteractableModalManager.cs
dal4segno 4ffbbb0aff 모든 네트워크 오브젝트의 소유권을 서버가 갖도록 함
Distributable -> None
관련 사이드 이펙트로 인한 버그 수정
2026-02-18 02:18:42 +09:00

158 lines
4.5 KiB
C#

using UnityEngine;
using Unity.Netcode;
namespace Northbound
{
public class InteractableModalManager : MonoBehaviour
{
[Header("UI Reference (Optional - auto-finds if null)")]
public InteractableModal interactableModal;
[Header("References")]
[SerializeField] private PlayerInteraction playerInteraction;
private IInteractable _currentInteractable;
private IInteractable _previousUnavailableInteractable;
private bool _isEnabled = false;
private void Awake()
{
if (playerInteraction == null)
{
playerInteraction = GetComponent<PlayerInteraction>();
}
FindModalComponent();
}
private void Start()
{
FindModalComponent();
// Start()에서 HideModal()을 호출하지 않음 - 첫 번째 Update에서 Modal이 표시되지 않는 문제 방지
// modalPanel과 unavailablePanel은 InteractableModal.Start()에서 이미 false로 설정됨
}
private void FindModalComponent()
{
if (interactableModal != null)
{
return;
}
InteractableModal[] modals = GetComponentsInChildren<InteractableModal>(true);
if (modals.Length > 0)
{
interactableModal = modals[0];
}
}
private void Update()
{
if (playerInteraction == null)
{
return;
}
bool isLocalPlayer = IsLocalPlayer();
if (!isLocalPlayer)
{
if (_isEnabled)
{
HideModal();
_isEnabled = false;
}
return;
}
_isEnabled = true;
IInteractable detectedInteractable = GetDetectedInteractable();
IInteractable unavailableInteractable = playerInteraction.CurrentUnavailableInteractable;
bool interactableChanged = detectedInteractable != _currentInteractable;
bool unavailableChanged = unavailableInteractable != _previousUnavailableInteractable;
if (interactableChanged || unavailableChanged)
{
_currentInteractable = detectedInteractable;
_previousUnavailableInteractable = unavailableInteractable;
if (_currentInteractable != null)
{
ShowModal(_currentInteractable);
}
else if (unavailableInteractable != null)
{
ShowUnavailableMessageModal(unavailableInteractable);
}
else
{
HideModal();
}
}
else if (_currentInteractable != null)
{
UpdateModalContent();
}
}
private bool IsLocalPlayer()
{
if (playerInteraction == null)
return false;
var networkPlayerController = playerInteraction.GetComponent<NetworkPlayerController>();
if (networkPlayerController != null)
{
return networkPlayerController.IsLocalPlayer;
}
return false;
}
private IInteractable GetDetectedInteractable()
{
var field = playerInteraction.GetType().GetField("_currentInteractable", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
if (field != null)
{
return field.GetValue(playerInteraction) as IInteractable;
}
return null;
}
private void ShowModal(IInteractable interactable)
{
if (interactableModal != null)
{
interactableModal.ShowModal(interactable);
}
}
private void HideModal()
{
if (interactableModal != null)
{
interactableModal.HideModal();
}
}
private void ShowUnavailableMessageModal(IInteractable interactable)
{
if (interactableModal != null)
{
interactableModal.ShowUnavailableMessage(interactable);
}
}
private void UpdateModalContent()
{
if (interactableModal != null)
{
interactableModal.UpdateModalContent();
}
}
}
}