74 lines
2.3 KiB
C#
74 lines
2.3 KiB
C#
using Unity.Netcode;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// Щит: удержание F — поднят (нет стрельбы, иммунитет к пулям, замедление).
|
|
/// Состояние синхронизируется через NetworkVariable (видно на клонах и у других игроков).
|
|
/// </summary>
|
|
public class PlayerShield : NetworkBehaviour
|
|
{
|
|
[SerializeField] private GameObject shieldVisual;
|
|
[SerializeField] private float shieldMoveSpeedMultiplier = 0.45f;
|
|
|
|
public NetworkVariable<bool> isActive = new NetworkVariable<bool>(false);
|
|
|
|
private PlayerHealth playerHealth;
|
|
private bool inputEnabled;
|
|
|
|
public bool IsShieldUp => isActive.Value;
|
|
public float MoveSpeedMultiplier => isActive.Value ? shieldMoveSpeedMultiplier : 1f;
|
|
|
|
public override void OnNetworkSpawn()
|
|
{
|
|
isActive.OnValueChanged += OnShieldChanged;
|
|
UpdateVisual(isActive.Value);
|
|
}
|
|
|
|
public override void OnNetworkDespawn()
|
|
{
|
|
isActive.OnValueChanged -= OnShieldChanged;
|
|
}
|
|
|
|
/// <summary> Владелец игрока — читает F и шлёт на сервер. </summary>
|
|
public void InitInput()
|
|
{
|
|
inputEnabled = true;
|
|
playerHealth = GetComponent<PlayerHealth>();
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!inputEnabled || !IsOwner) return;
|
|
if (playerHealth != null && playerHealth.isDead.Value) return;
|
|
|
|
bool _wantShield = Input.GetKey(KeyCode.F);
|
|
if (_wantShield == isActive.Value) return;
|
|
|
|
SetShieldServerRpc(_wantShield);
|
|
}
|
|
|
|
/// <summary> Сервер: для клонов при воспроизведении записи. </summary>
|
|
public void SetShieldState(bool _active)
|
|
{
|
|
if (!IsServer) return;
|
|
isActive.Value = _active;
|
|
}
|
|
|
|
[ServerRpc]
|
|
private void SetShieldServerRpc(bool _active)
|
|
{
|
|
if (playerHealth == null) playerHealth = GetComponent<PlayerHealth>();
|
|
if (playerHealth != null && playerHealth.isDead.Value) return;
|
|
|
|
isActive.Value = _active;
|
|
}
|
|
|
|
private void OnShieldChanged(bool _previous, bool _current) => UpdateVisual(_current);
|
|
|
|
private void UpdateVisual(bool _active)
|
|
{
|
|
if (shieldVisual != null)
|
|
shieldVisual.SetActive(_active);
|
|
}
|
|
}
|