102 lines
2.9 KiB
C#
102 lines
2.9 KiB
C#
using Unity.Netcode;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
public sealed class PlayerInteractionController : NetworkBehaviour, IPlayerSystem
|
|
{
|
|
[SerializeField, Min(0.1f)] private float interactionDistance = 3f;
|
|
[SerializeField] private LayerMask interactionMask = ~0;
|
|
|
|
private Camera playerCamera;
|
|
private IInteractable focusedInteractable;
|
|
private IPlayerInteractionSession activeSession;
|
|
private bool activeSessionReleaseRequested;
|
|
private bool isInitialized;
|
|
|
|
public void Initialize(PlayerFacade facade)
|
|
{
|
|
playerCamera = GetComponentInChildren<Camera>(true);
|
|
isInitialized = playerCamera != null;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!isInitialized || !IsOwner || Keyboard.current == null)
|
|
return;
|
|
|
|
if (PlayerInteractionSessionRegistry.TryGetControlledSession(
|
|
OwnerClientId,
|
|
out activeSession))
|
|
{
|
|
focusedInteractable = null;
|
|
|
|
if (!Keyboard.current.eKey.isPressed && !activeSessionReleaseRequested)
|
|
{
|
|
activeSessionReleaseRequested = true;
|
|
activeSession.RequestRelease();
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
activeSession = null;
|
|
activeSessionReleaseRequested = false;
|
|
focusedInteractable = FindFocusedInteractable();
|
|
|
|
if (Keyboard.current.eKey.wasPressedThisFrame &&
|
|
focusedInteractable != null &&
|
|
focusedInteractable.IsInteractionAvailable)
|
|
{
|
|
focusedInteractable.RequestInteraction();
|
|
}
|
|
}
|
|
|
|
private IInteractable FindFocusedInteractable()
|
|
{
|
|
Ray ray = new(playerCamera.transform.position, playerCamera.transform.forward);
|
|
if (!Physics.Raycast(ray, out RaycastHit hit, interactionDistance, interactionMask, QueryTriggerInteraction.Collide))
|
|
return null;
|
|
|
|
foreach (MonoBehaviour component in hit.collider.GetComponentsInParent<MonoBehaviour>())
|
|
{
|
|
if (component is IInteractable interactable)
|
|
return interactable;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
if (!IsOwner)
|
|
return;
|
|
|
|
if (activeSession != null)
|
|
{
|
|
DrawPrompt(activeSession.ReleasePrompt);
|
|
return;
|
|
}
|
|
|
|
if (focusedInteractable == null)
|
|
return;
|
|
|
|
string prompt = focusedInteractable.IsInteractionAvailable
|
|
? "[E] " + focusedInteractable.InteractionPrompt
|
|
: "In use";
|
|
DrawPrompt(prompt);
|
|
}
|
|
|
|
private static void DrawPrompt(string prompt)
|
|
{
|
|
GUIStyle style = new(GUI.skin.label)
|
|
{
|
|
alignment = TextAnchor.MiddleCenter,
|
|
fontSize = 16,
|
|
normal = { textColor = Color.white }
|
|
};
|
|
|
|
Rect area = new(0f, Screen.height * 0.62f, Screen.width, 28f);
|
|
GUI.Label(area, prompt, style);
|
|
}
|
|
}
|