Client Firing

I can not seem to get the client side to fire for some reason. Client side can see server firing, but it will not activate on client. Anyone have any ideas? Also, NetworkServer.Spawn(projectileInstance, connectionToClient); just spawns it on the client side when server shoots, I don’t understand how the client will call the entire shoot logic if its wrapped in a [servercallback] on update().

Thanks for any help!

Hi there, the server should spawn the projectile and then since the projectile has a networkIdentity and a networkTransform, it’s synced across the clients. Is your projectile prefab set up correctly in the editor?

Yes, i have the projectile prefab as a network ident and as the prefab to spawn. The client side isn’t firing at all for some reason, but the client side registers the server shots.

When you say the client side isn’t firing, do you mean the projectile isn’t showing up on the client side? If you run the client only version in the editor, does the projectile appear in the hierarchy?

Correct. I just re-tested to verify it. When running client side, it does not even instantiate the prefab for firing. I even have the debug.log back in there for testing, and that is not even firing off.

Sorry, so the when the Server fires are those projectiles seen on the Client side? But when the client fires, no projectiles are instantiated?

This sounds like an issue with the targeter not the firing. Can you check if the target is set on update of the UnitFiring? Maybe post your targeter code here?

Correct, server side can fire and shown on both sides server and client. Client can not instantiate anything even a debug.log.
I have modified it a bit since and am basing it only on a click input instead of a target. Basically 90% same code w/o the targeter, but here is the unit firing code.

using Mirror;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.ProBuilder;

public class UnitFiring : NetworkBehaviour
{

[SerializeField] private GameObject projectilePrefab = null;
[SerializeField] private Transform projectileSpawnPoint = null;
[SerializeField] private float fireRate = 1f;
private Camera mainCamera;

private float lastFireTime;

[ServerCallback]
private void Update()
{
    if (!hasAuthority) { return; }
    mainCamera = Camera.main;
    if (Mouse.current.leftButton.isPressed)
    {
        if (!CanFireAtTarget()) { return; }
        if (Time.time > (1 / fireRate) + lastFireTime)
        {
            Ray ray = mainCamera.ScreenPointToRay(Mouse.current.position.ReadValue());   //gets mouse in current location of screen
            if (!Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity)) { return; } ; //sends out ray from mouse click to see if it hit anything

            Quaternion projectileRotation = Quaternion.LookRotation(hit.point - projectileSpawnPoint.position);// From target is, minus our position
            GameObject projectileInstance = Instantiate(projectilePrefab, projectileSpawnPoint.position, projectileRotation);
            //we can now fire
            Debug.Log("Fire!!!");
            
            NetworkServer.Spawn(projectileInstance, connectionToClient);
            

            lastFireTime = Time.time;
        }
    }

}

[Server]
private bool CanFireAtTarget()
{
    
        return true;
    
}

}

Thanks.

Hi,

I think the issue is the way you tied it into the mouse click. Since Update is a [ServerCallback], this is only checking for mouse clicks on the server side. So only when the server clicks are you able to fire. You will need to add the click check somewhere else. I suggest doing this in the Targeter script. Hope this helps!

That does make alot of sense actually! I may need to redo some things. Is there a clientcallback option i can use on the same script as well? Or is it b/c its on the update and there can only be 1 update.

You could create another method and give it the [Client] attribute, and then call it it update. However, in the course we put the targeter on the client side and firing on the server side. This is a good way to separate the behaviour in terms of server/client separation, but also in terms of Unit behaviour separation. For example, if later you wanted to make a computer player with AI, it would have to target as well for firing, and there would be no mouse click.

True. i will test making the targeter when i get home from work and see if it works! Thanks for the help!

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

Privacy & Terms