Added leveler

This commit is contained in:
2026-08-07 11:40:20 +03:00
parent d9d7ee49d2
commit e3746e3e9d
22 changed files with 2824 additions and 383 deletions
@@ -5,12 +5,20 @@ public sealed class FirstPersonCameraController : NetworkBehaviour, IPlayerSyste
{
[SerializeField, Range(1f, 89f)] private float verticalLookLimit = 80f;
private readonly NetworkVariable<float> synchronizedPitch = new(
0f,
NetworkVariableReadPermission.Everyone,
NetworkVariableWritePermission.Owner);
private Camera playerCamera;
private AudioListener audioListener;
private MeshRenderer playerRenderer;
private float pitch;
private bool isInitialized;
public Transform AimTransform => playerCamera != null ? playerCamera.transform : transform;
public Vector3 AimForward => AimTransform.forward;
public void Initialize(PlayerFacade facade)
{
playerCamera = GetComponentInChildren<Camera>(true);
@@ -24,6 +32,9 @@ public sealed class FirstPersonCameraController : NetworkBehaviour, IPlayerSyste
bool isLocalPlayer = IsOwner;
playerCamera.gameObject.SetActive(isLocalPlayer);
if (!isLocalPlayer)
ApplyCameraPitch(synchronizedPitch.Value);
if (!isLocalPlayer)
return;
@@ -43,21 +54,48 @@ public sealed class FirstPersonCameraController : NetworkBehaviour, IPlayerSyste
Cursor.visible = false;
}
public override void OnNetworkSpawn()
{
synchronizedPitch.OnValueChanged += HandleSynchronizedPitchChanged;
if (isInitialized && !IsOwner)
ApplyCameraPitch(synchronizedPitch.Value);
}
public void ApplyPitch(float pitchDelta)
{
if (!isInitialized || !IsOwner)
return;
pitch = Mathf.Clamp(pitch - pitchDelta, -verticalLookLimit, verticalLookLimit);
playerCamera.transform.localRotation = Quaternion.Euler(pitch, 0f, 0f);
ApplyCameraPitch(pitch);
if (IsSpawned)
synchronizedPitch.Value = pitch;
}
public override void OnNetworkDespawn()
{
synchronizedPitch.OnValueChanged -= HandleSynchronizedPitchChanged;
if (IsOwner)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
private void HandleSynchronizedPitchChanged(float _, float currentPitch)
{
if (!IsOwner)
ApplyCameraPitch(currentPitch);
}
private void ApplyCameraPitch(float currentPitch)
{
pitch = currentPitch;
if (playerCamera != null)
playerCamera.transform.localRotation = Quaternion.Euler(pitch, 0f, 0f);
}
}
@@ -0,0 +1,27 @@
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
public sealed class PlayerCarryController : NetworkBehaviour, IPlayerSystem
{
private bool isInitialized;
public void Initialize(PlayerFacade facade)
{
isInitialized = true;
}
private void Update()
{
if (!isInitialized || !IsOwner || Keyboard.current == null)
return;
if (Keyboard.current.gKey.wasPressedThisFrame &&
NetworkHeldInteractable.TryGetHeldObject(
OwnerClientId,
out NetworkHeldInteractable heldObject))
{
heldObject.RequestThrow();
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 5e63651da7abbf744bc45585a2133e6f
@@ -9,6 +9,8 @@ public sealed class PlayerInteractionController : NetworkBehaviour, IPlayerSyste
private Camera playerCamera;
private IInteractable focusedInteractable;
private IPlayerInteractionSession activeSession;
private bool activeSessionReleaseRequested;
private bool isInitialized;
public void Initialize(PlayerFacade facade)
@@ -22,6 +24,23 @@ public sealed class PlayerInteractionController : NetworkBehaviour, IPlayerSyste
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 &&
@@ -49,9 +68,26 @@ public sealed class PlayerInteractionController : NetworkBehaviour, IPlayerSyste
private void OnGUI()
{
if (!IsOwner || focusedInteractable == null)
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,
@@ -59,12 +95,7 @@ public sealed class PlayerInteractionController : NetworkBehaviour, IPlayerSyste
normal = { textColor = Color.white }
};
string prompt = focusedInteractable.IsInteractionAvailable
? "[E] " + focusedInteractable.InteractionPrompt
: "In use";
Rect area = new(0f, Screen.height * 0.62f, Screen.width, 28f);
GUI.Label(area, prompt, style);
}
}