N
N
not important .2021-10-27 08:24:44
Unity
not important ., 2021-10-27 08:24:44

How to sync bullet with server?

I am trying to sync client bullet with server, here is the code:

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

public class PlayerShoot : NetworkBehaviour {

    public PlayerShoot PlayerShootScript;
    public Player PlayerScript;
    public LayerMask WeaponEnemyLayers;
    [Space]
    public Transform[] WeaponfirePoints;
    public GameObject[] WeaponBulletPrefab;
    [Space]
    public float WeaponScatter;
    public float WeaponBulletForce;
    [Space]
    public int WeaponMinDamage;
    public int WeaponMaxDamage;
    public int WeaponChanceCritDamage;
    public int WeaponCritDamage;
    [Space]
    public int WeaponOtskoks = 0;
    public int WeaponProshivanies = 0;

    void Update() {

        if(isLocalPlayer)
        if(PlayerScript.currentWeaponScript == null) { return; }

        WeaponfirePoints = PlayerScript.currentWeaponScript.firePoints;
        WeaponScatter = PlayerScript.currentWeaponScript.scatter;
        WeaponBulletForce = PlayerScript.currentWeaponScript.bulletForce;
        WeaponBulletPrefab = PlayerScript.currentWeaponScript.bulletPrefab;

        WeaponMinDamage = PlayerScript.currentWeaponScript.minDamage;
        WeaponMaxDamage = PlayerScript.currentWeaponScript.maxDamage;
        WeaponChanceCritDamage = PlayerScript.currentWeaponScript.chanceCritDamage;
        WeaponCritDamage = PlayerScript.currentWeaponScript.critDamage;

        WeaponOtskoks = PlayerScript.currentWeaponScript.otskoks;
        WeaponProshivanies = PlayerScript.currentWeaponScript.proshivanies;

        WeaponEnemyLayers = PlayerScript.currentWeaponScript.enemyLayers;

        if(Input.GetButtonDown("Fire1")) { PlayerScript.currentWeaponScript.mouseHide = true; }
        if(Input.GetButtonUp("Fire1")) { PlayerScript.currentWeaponScript.mouseHide = false; }

        if(PlayerScript.currentWeaponScript.weaponReloadnig) { return; }
        if(!PlayerScript.currentWeaponScript.weaponReadyToShoot) { return; }

        if(PlayerScript.currentWeaponScript.categoryWeapon == "Огнестрельное") { 

            if(PlayerScript.currentWeaponScript.mouseHide) {

                Shoot();
        
            }
                
        }
        
    }

    [Client]
    void Shoot() {

        CmdSpawnBullet();
        if(!PlayerScript.currentWeaponScript.infiniteMode) { PlayerScript.currentWeaponScript.currentAmmo -= 1; }

    }
    
    [Command]
    void CmdSpawnBullet() {

        for (int i = 0; i < WeaponfirePoints.Length; i++) {

            Vector3 Angle = WeaponfirePoints[i].eulerAngles;
            Angle.z += Random.Range(-WeaponScatter, WeaponScatter);
            GameObject bullet = GameObject.Instantiate(WeaponBulletPrefab[Random.Range(0, WeaponBulletPrefab.Length)], WeaponfirePoints[i].position, Quaternion.Euler(Angle));

            Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
            rb.velocity = bullet.transform.right * WeaponBulletForce;
            
            int damage = Random.Range(WeaponMinDamage, WeaponMaxDamage+1);
            bool CRIT = false;

            NetworkServer.Spawn(bullet);
            
            Bullet bulletScript = bullet.GetComponent<Bullet>();
            bulletScript.EarlyShoot(PlayerShootScript);
            bulletScript.DamageMastery(WeaponOtskoks, WeaponProshivanies, damage, WeaponCritDamage, WeaponChanceCritDamage, WeaponEnemyLayers);

        }

    }

    [Command]
    public void CmdHitOn(string _playerTag, string _playerID, int _damage, bool CRITICAL_DAMAGE) {

        if(CRITICAL_DAMAGE) {

            if(_playerTag == "Player") {

                Player _player = GameManager.GetPlayer(_playerID);
                _player.TakeCritDamage(_damage);

            }

        } else {

            if(_playerTag == "Player") {

                Player _player = GameManager.GetPlayer(_playerID);
                _player.TakeDamage(_damage);

            }

        }

    }

}


When the server shoots, the client sees them, but the client itself cannot shoot, I partially understand why, but I do not understand how to make the client be able to shoot and the server see his shots.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
dollar, 2021-10-27
@dollar

This is a very difficult task (in terms of game design).
The solution usually boils down to either no bullet, a homing bullet, or a lack of accurate bullet synchronization between client and server. Well, either in the requirements for the game you need to prescribe an extremely low ping and no packet loss.

R
rPman, 2021-10-27
@rPman

Specifically, on the question of why the 'client cannot shoot' xs, you need to debug, or at least arrange the logging in the code
. But the implementation of the correct synchronization of the client-server is really a very difficult task.
One way to solve it is to implement all the logic of all the dynamics only on the server, and the clients work exclusively for display. Those. when the client sends literally button presses to the server (more precisely, primary actions), they are sent to the server, it processes them, and any changes (state changes, moving, creating and deleting objects) are already sent by the server to clients.
Advantage - ease of implementation, auto-sync, simplification of creating anti-cheats (for example, the client cannot give the wrong speed or apply the wrong actions in such a situation), low network traffic from the client to the server.
The disadvantage of the approach is tangible lags, when the Internet speed is low, you can also 'fight' with them, only visually hide the delay if, in order to display information about critical objects, the client duplicates their processing in parallel with the server, but the final result is still received from the server (as a result the bullet can 'bounce back' during a straight flight or disappear if it turns out that a target drove up under it and the client considered that he missed, etc.)
Another disadvantage is the high load on the server (and it should be like this anyway, in order to combat cheats, the server must serve all objects centrally), high load on the server network (the server constantly sends information to all its clients, and this is the square of the number of players).
A good way to deal with the load on the server can be p2p, when data about changes processed by clients in parallel with the server are sent not through the server, but directly to clients, and the server sends only the hashes of the result. This will greatly complicate the code (I have not heard that large projects do this), but it will solve a lot of problems with both lags and high server costs.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question