Files
FORT-BO/Assets/CONTENT/Game/Scripts/Player/FirstPersonCameraController.cs
T
2026-08-07 11:40:20 +03:00

102 lines
2.8 KiB
C#

using Unity.Netcode;
using UnityEngine;
public sealed class FirstPersonCameraController : NetworkBehaviour, IPlayerSystem
{
[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);
audioListener = playerCamera != null ? playerCamera.GetComponent<AudioListener>() : null;
playerRenderer = GetComponentInChildren<MeshRenderer>();
isInitialized = playerCamera != null;
if (!isInitialized)
return;
bool isLocalPlayer = IsOwner;
playerCamera.gameObject.SetActive(isLocalPlayer);
if (!isLocalPlayer)
ApplyCameraPitch(synchronizedPitch.Value);
if (!isLocalPlayer)
return;
if (playerRenderer != null)
playerRenderer.enabled = false;
foreach (Camera camera in FindObjectsByType<Camera>(FindObjectsSortMode.None))
{
if (camera != playerCamera)
camera.enabled = false;
}
if (audioListener != null)
audioListener.enabled = true;
Cursor.lockState = CursorLockMode.Locked;
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);
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);
}
}