No projectile in host view

I have an interesting problem. Left side is the host and right side is the client who joined. Client can see bullets instantiated by both the host and itself. On contrary host side cant see either it’s own bullets or client side’s. In my code working principle is simple first it creates a dummy object for itself then sends a signal to the server. Server creates a game object at same position without any sprite then send every client a signal. Client’s check if they are the owner and if they are not they create the gameobject on themselves (this check is for being sure the one who already fired the bullet does not see it twice).

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

public class WeaponController : NetworkBehaviour
{
    PlayerControls playerControls;
    bool attackButtonDown = false;
    bool isAttacking = false;
    bool isOnCooldown = false;

    [Header("Variables")]
    [SerializeField] float attackCooldown = .5f;
    
    [Header("References")]
    [SerializeField] GameObject serverProjectilePrefab;
    [SerializeField] GameObject clientProjectilePrefab;
    [SerializeField] Transform projectileSpawnTransform;
    
    private void Awake() {
        playerControls = new PlayerControls();
    }

    public override void OnNetworkSpawn()
    {
        if(!IsOwner) {return;}
        playerControls.Combat.PrimaryFire.started += _ => StartAttacking();
        playerControls.Combat.PrimaryFire.canceled += _ => StopAttacking();
    }

    public override void OnNetworkDespawn()
    {
        if(!IsOwner) {return;}
        playerControls.Combat.PrimaryFire.started -= _ => StartAttacking();
        playerControls.Combat.PrimaryFire.canceled -= _ => StopAttacking();
    }
    private void FixedUpdate() {
        if(!IsOwner) {return;}
        FaceMouse();
        Fire();
    }

    private void OnEnable() {
        playerControls.Enable();
    }

    private void OnDisable() {
        playerControls.Disable();
    }

    private void StartAttacking()
    {
        attackButtonDown = true;
    }

    private void StopAttacking()
    {
        attackButtonDown = false;
    }

    private void FaceMouse()
    {
        Vector2 mousePosition = playerControls.Combat.Aim.ReadValue<Vector2>();
        mousePosition = Camera.main.ScreenToWorldPoint(mousePosition);
        Vector2 direction = new Vector2(transform.position.x - mousePosition.x, transform.position.y - mousePosition.y);
        transform.up = -direction;
    }

    private void Fire()
    {
        if(attackButtonDown)
        {
            if(!isAttacking && !isOnCooldown)
            {
                isAttacking = true;
                isOnCooldown = true;
                SpawnServerRpc(projectileSpawnTransform.position, this.transform.up);
                SpawnDummyProjectile(projectileSpawnTransform.position, this.transform.up);
                isAttacking = false;
                StartCoroutine(AttackCooldownRoutine());
            }
        }
    }

    private void SpawnDummyProjectile(Vector3 spawnPos, Vector3 direction)
    {
        Debug.Log("Spawning Dummy Projectile");
        GameObject projectileInstance = Instantiate(
                            clientProjectilePrefab,
                            spawnPos,
                            Quaternion.identity
                            );
        projectileInstance.transform.up = direction;
    }

    [ServerRpc]
    private void SpawnServerRpc(Vector3 spawnPos, Vector3 direction)
    {
        GameObject projectileInstance = Instantiate(
                            serverProjectilePrefab,
                            spawnPos,
                            Quaternion.identity
                            );
        projectileInstance.transform.up = direction;
        SpawnClientRpc(spawnPos, direction);
    }

    [ClientRpc]
    private void SpawnClientRpc(Vector3 spawnPos, Vector3 direction)
    {
        if(IsOwner) return;

        SpawnDummyProjectile(spawnPos, direction);
    }

    private IEnumerator AttackCooldownRoutine()
    {
        
        yield return new WaitForSeconds(attackCooldown);
        isOnCooldown = false;
    }

}

Hi there,
My best guess is that the host projectiles are colliding with the tank that is firing them, and being destroyed immediately.

At some point in the course we add the line:
Physics2D.IgnoreCollision(playerCollider, projectileInstance.GetComponent<Collider2D>());

This goes in the SpawnDummyProjectile after the dummy projectile is instantiate.

Hi first of all thanks for the response :slight_smile: I dont think that it can be the reason as i can see them on client screen. And i can not see any projectile fired by client in the host screen :confused:

Are you able to share your destroyOnCollision script? It is possible they are getting destroyed immediately on the host but not the server.

Oh interesting here is the code :slight_smile:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroySelfOnContact : MonoBehaviour
{
    private void OnTriggerEnter2D(Collider2D other) {
        Destroy(gameObject);
    }
}

Okay so definitely network independent :sweat_smile:
So are you able to confirm the dummy projectiles are spawning on the host?
The other issue here could be the rendering layer. They could be rending underneath the ground?

Hmmm the thing is its not even creating the gameobject
image
here i checked firing and there is no new gameobject anywhere

Okay, if you upload your project here I can take a look:
https://gdev.tv/projectupload
My best guess is still that it’s being destroyed right away. So the other thing you can try is put a debug.log in the DestroySelfOnContact class and see if it’s colliding with anything right after it spawns. If it was destroyed the same frame, you wouldn’t see anything in the hierarchy.

First of all thanks a lot for the help! I put the debug.log and saw that it worked so started to think what it might be. I wanted it to collide with other bullets so the collusion between bullets were open in my project. Normally this is not a problem as i have a cooldown but if you are server its different. When you are the server both dummy projectile and serverrpc projectile instantiated on your pc so they collide and destroy each other. I clossed it for now but in future i will change it as only same prefab bullets can collide so that server rpc wont create a problem with client rpc.

1 Like

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

Privacy & Terms