Another question about fire rate muzzle flash for the NGO cource

These might have just been “it’s what we choose” questions but I wanted to ask about your approach to limiting fire rate and showing muzzle flash my code for this is as follows

using System.Collections;
using Unity.Netcode;
using UnityEngine;

public class PlayerShoot : NetworkBehaviour
{
    [Header("References")]
    [SerializeField] private InputReader inputReader;
    [SerializeField] private GameObject serverProjectilePrefab;
    [SerializeField] private GameObject clientProjectilePrefab;
    [SerializeField] private Transform projectileSpawnPoint;
    [SerializeField] private GameObject muzzleFlash;
    [SerializeField] private Collider2D playerCollider;
    
    [Header("Shooting Settings")]
    [SerializeField] private float fireRate = 0.25f;
    [SerializeField] private float projectileSpeed = 5f;
    [SerializeField] private float muzzleFlashDuration = 0.1f;
    
    private float _shootTimer;
    private bool shouldFire;
    
    public override void OnNetworkSpawn()
    {
        if (!IsOwner) return;
        inputReader.PrimaryFireEvent += HandlePrimaryFire;
    }

    private void HandlePrimaryFire(bool fire)
    {
        shouldFire = fire;
    }

    private void Update()
    {
        if (!IsOwner) 
            return;
        
        _shootTimer += Time.deltaTime;
        
        bool canFire = _shootTimer >= fireRate;
        if (!canFire || !shouldFire) 
            return;
        
        _shootTimer = 0f;
        var spawnPos = projectileSpawnPoint.position;
        var spawnDir = projectileSpawnPoint.up;
        
        SpawnDummyProjectile(spawnPos, spawnDir);
        PrimaryFireServerRpc(spawnPos, spawnDir);
    }

    //spawn on client right away to reduce felt lag
    private void SpawnDummyProjectile(Vector3 spawnPos, Vector3 direction)
    {
        StartCoroutine(ShowMuzzleFlash());
       
        var clientProjectileInstance = Instantiate(clientProjectilePrefab, spawnPos, Quaternion.identity);
        clientProjectileInstance.transform.up = direction;
        
        Physics2D.IgnoreCollision(playerCollider, clientProjectileInstance.GetComponent<Collider2D>());
        SetProjectileVelocity(clientProjectileInstance);
        
    }
    private void SetProjectileVelocity(GameObject projectileInstance)
    {
        if (projectileInstance.TryGetComponent<Rigidbody2D>(out var rb))
            rb.velocity = rb.transform.up * projectileSpeed;
    }

    [ServerRpc]
    private void PrimaryFireServerRpc(Vector3 spawnPos, Vector3 direction)
    {
        var serverProjectileInstance = Instantiate(serverProjectilePrefab, spawnPos, Quaternion.identity);
        serverProjectileInstance.transform.up = direction;
        
        Physics2D.IgnoreCollision(playerCollider, serverProjectileInstance.GetComponent<Collider2D>());
        SetProjectileVelocity(serverProjectileInstance);
        
        SpawnDummyProjectileClientRpc(spawnPos, direction);
    }

    [ClientRpc]
    private void SpawnDummyProjectileClientRpc(Vector3 spawnPos, Vector3 direction)
    {
        if (IsOwner)
            return;
        
        SpawnDummyProjectile(spawnPos, direction);
    }
    
    private IEnumerator ShowMuzzleFlash()
    {
        muzzleFlash.SetActive(true);
        yield return new WaitForSeconds(muzzleFlashDuration);
        muzzleFlash.SetActive(false);
    }

    public override void OnNetworkDespawn()
    {
        if (!IsOwner) return;
        inputReader.PrimaryFireEvent -= HandlePrimaryFire;
    }
}

This all works fine - I am wondering why you didn’t just use _shootTimer += Time.deltaTime and resetting it on fire - the approach shown for limiting rate seems a little convoluted, especially given we are trusting the client on this anyways. For the muzzle flash, is there any reason not to use a co-routine like I did to handle this?

As you correctly state in programming there are always multiple ways to do things and different programmers do things differently.
Some use co-routines a lot and that can cause its own issues with if they are not properly ended and so others may avoid them unless they are absolutely necessary.

My personal view is if it works and is not causing any issues then use them

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms