Your script looks good for the most part. However, there are a few things to consider and potentially improve:
Input System Integration: You're currently using the legacy Input.GetKeyDown(KeyCode.E) and Gamepad.current to detect input. It's recommended to fully utilize Unity's new Input System for a more robust and flexible input handling solution.
Network Synced Variables: Ensure that any variables affecting gameplay logic, such as isComputerScreenVisible and isInteracting, are properly synchronized across the network. This ensures consistency between the client and server.
Interaction Range Check: Make sure that the interaction range check (IsPlayerInRange()) accurately represents the intended behavior. You may want to use a sphere cast or other methods to check for obstacles between the player and the interactive computer.
Input Handling: Consider handling input detection on the client side and then sending commands to the server to perform interactions. This helps reduce latency and ensures a smoother player experience.
Error Handling: Implement error handling to handle edge cases, such as when there are no connected players or when the gamepad is disconnected.
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
public class InteractiveComputer : NetworkBehaviour
{
public GameObject computerScreen;
public float interactionRange = 3f;
private float displayDuration = 5f;
private bool isComputerScreenVisible = false;
private bool isInteracting = false;
void Update()
{
if (!IsClient)
return;
if (IsPlayerInRange())
{
if (Keyboard.current != null && Keyboard.current.eKey.wasPressedThisFrame && !isInteracting)
{
InteractWithComputerClientRpc();
}
if (Gamepad.current != null && Gamepad.current.buttonSouth.wasPressedThisFrame && !isInteracting)
{
InteractWithComputerClientRpc();
}
}
}
[ClientRpc]
private void InteractWithComputerClientRpc()
{
isComputerScreenVisible = true;
computerScreen.SetActive(true);
Invoke(nameof(HideComputerScreenClientRpc), displayDuration);
isInteracting = true;
}
[ClientRpc]
private void HideComputerScreenClientRpc()
{
isComputerScreenVisible = false;
computerScreen.SetActive(false);
isInteracting = false;
}
bool IsPlayerInRange()
{
foreach (var player in NetworkManager.Singleton.ConnectedClientsList)
{
if (player != null && Vector3.Distance(transform.position, player.PlayerObject.transform.position) <= interactionRange)
{
return true;
}
}
return false;
}
}
Please remember to thoroughly test your implementation to ensure it behaves as expected in both single-player and multiplayer scenarios. Additionally, consider adding error handling and edge case checks to make your script more robust.