S
S
Senture2018-04-12 15:23:33
Unity
Senture, 2018-04-12 15:23:33

Synchronization of the selected weapon for each of the players in a multiplayer shooter on Unity?

Hello everybody!
There is a code for synchronizing the position, rotation of the players, and it also has a code for synchronizing the selected weapon for each of the players:

spoiler
/*
 * 
 * Скрипт SyncPlayer отвечает за синхранизацию игроков
 * 
 */
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class SyncPlayer : NetworkBehaviour
{
    [SyncVar] Vector3 syncPosition; // Позиция всех клиентов кроме самого игрока
    [SyncVar] Quaternion syncRotation; // Поворот всех игроков кроме самого игрока
    [SyncVar] SyncListBool syncWeapon = new SyncListBool();

    public float lerpSpeed = 20; // Скорость сглаживания

    /// <summary>
    /// Фиксированый вызов метода TransmitPosition для синхронизации позиции
    /// </summary>
  void FixedUpdate ()
    {
        LerPosition();
        TransmitTransform();
    }

    /// <summary>
    /// Метод для сглаживания позиции всех клиентов но кроме самого игрока
    /// </summary>
    void LerPosition()
    {
        if (!isLocalPlayer)
        {
            transform.position = Vector3.Lerp(transform.position, syncPosition, Time.deltaTime * lerpSpeed);
            transform.rotation = Quaternion.Lerp(transform.rotation, syncRotation, Time.deltaTime * lerpSpeed);

            for(int i = 0; i < syncWeapon.Count; i++)
            {
                gameObject.GetComponent<PlayerScrolWeapon>().weapon[i].SetActive(syncWeapon[i]);
            }

        }
    }

    /// <summary>
    /// Отправка позиции локального игрока на сервер в переменную syncPosition
    /// </summary>
    [Client]
    void TransmitTransform()
    {
        if (isLocalPlayer)
        {
            List<GameObject> weapon = gameObject.GetComponent<PlayerScrolWeapon>().weapon;
            GameObject[] _weapon = new GameObject[4];

            int i = 0;

            foreach (GameObject goGun in weapon)
            {
                _weapon[i] = goGun;
                i++;
            }

            CmdSendTransform(transform.position, transform.rotation, _weapon);
        }
    }

    /// <summary>
    /// Запись позиции локального игрока в переменную syncPosition
    /// </summary>
    [Command]
    void CmdSendTransform(Vector3 position, Quaternion rotation, GameObject[] _weapon)
    {
        syncPosition = position;
        syncRotation = rotation;

        syncWeapon.Clear();
        foreach (GameObject weap in _weapon)
        {
            syncWeapon.Add(weap.activeSelf);
        }
    }
}


The PlayerScrollWeapon script itself:
spoiler
using System.Collections.Generic;
using UnityEngine;

public class PlayerScrolWeapon : MonoBehaviour
{

    [SerializeField] private GameObject[] weapons; // Массив всех оружий
    private string[] nameSelectedWeapons = new string[4]; // Массив названий всех выбранных оружий
    public List<GameObject> weapon = new List<GameObject>(); // Список всех выбранных оружий для переключения между ними
    private int scrolInt = 0; // Индекс выбранного оружия(скрола)
    private int lastScrolInt = 0; // Индекс старого значения
    private Animator anim;
  void Start ()
    {
        anim = GetComponent<Animator>();
        nameSelectedWeapons[0] = "Cube Gun";
        nameSelectedWeapons[1] = "Sphere Gun";
        nameSelectedWeapons[2] = "Cylinder Gun";
        nameSelectedWeapons[3] = "Capsule Gun";
        // Переносим в список выбранных оружий из массива всех оружий по названиям оружий в массиве названий
        foreach (GameObject goWeapon in weapons)
        {
            foreach(string nameSelectedWeapon in nameSelectedWeapons)
            {
                if (nameSelectedWeapon == goWeapon.name)
                    weapon.Add(goWeapon);
            }
        }

        weapon[scrolInt].SetActive(true);
 	}
  
  void Update ()
    {
        lastScrolInt = scrolInt;
        // Изменение значения индекса выбранного оружия при прокрутке колесиком мыши
        if (Input.GetAxis("Mouse ScrollWheel") > 0f)
            scrolInt++;
        else if(Input.GetAxis("Mouse ScrollWheel") < 0f)
            scrolInt--;

        // Не даем выйти индексу за пределы допустимого
        if (scrolInt > weapon.Count - 1)
            scrolInt = 0;
        else if(scrolInt < 0)
            scrolInt = weapon.Count - 1;

        // Переключение между разными оружиями
        if (lastScrolInt != scrolInt)
        {
            //Debug.Log(scrolInt);
            for (int i = 0; i < weapon.Count; i++)
            {
                if (i == scrolInt)
                    weapon[i].SetActive(true);
                else
                    weapon[i].SetActive(false);
            }
        }
  }
}


When starting the host, when 1 player is only on the stage (the server itself and the client), then everything is OK, after the client (2nd player) connects, the server stops and gives the following error:
spoiler

NullReferenceException: Object reference not set to an instance of an object
SyncPlayer.CmdSendTransform (Vector3 position, Quaternion rotation, UnityEngine.GameObject[] _weapon) (at Assets/Scripts/Player/SyncPlayer.cs:80)
SyncPlayer.InvokeCmdCmdSendTransform (UnityEngine.Networking.NetworkBehaviour obj, UnityEngine.Networking.NetworkReader reader)
UnityEngine.Networking.NetworkIdentity.HandleCommand (Int32 cmdHash, UnityEngine.Networking.NetworkReader reader) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:618)
UnityEngine.Networking.NetworkServer.OnCommandMessage (UnityEngine.Networking.NetworkMessage netMsg) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1281)
UnityEngine.Networking.NetworkConnection.HandleReader (UnityEngine.Networking.NetworkReader reader, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:469)
UnityEngine.Networking.NetworkConnection.HandleBytes (System.Byte[] buffer, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:425)
UnityEngine.Networking.NetworkConnection.TransportReceive (System.Byte[] bytes, Int32 numBytes, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:576)
UnityEngine.Networking.NetworkServer.OnData (UnityEngine.Networking.NetworkConnection conn, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:738)
UnityEngine.Networking.NetworkServer+ServerSimpleWrapper.OnData (UnityEngine.Networking.NetworkConnection conn, Int32 receivedSize, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1869)
UnityEngine.Networking.NetworkServerSimple.HandleData (Int32 connectionId, Int32 channelId, Int32 receivedSize, Byte error) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServerSimple.cs:384)
UnityEngine.Networking.NetworkServerSimple.Update () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServerSimple.cs:247)
UnityEngine.Networking.NetworkServer.InternalUpdate () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:691)
UnityEngine.Networking.NetworkServer.Update () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:642)
UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:1091)

But the client can see which weapon was selected from the server until it stops. When trying to unpause the server, the same error occurs. I have already tried many options and all were unsuccessful, I decided to stop on this option. it seems to me the most correct.
Please help me fix this error.
PS Thank you very much!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Senture, 2018-04-12
@Senture

The problem was solved, this was due to the fact that 2 client and server applications were launched on 1pc, after the server and client were launched on different PCs, almost everything worked, but for some reason the client sees how the server changes weapons, but the server does not see how the client changes weapons. Does anyone have a solution to this problem?
That no one knows how to do it? I've already searched the entire Internet about changing weapons in multiplayer and synchronizing them, but it's empty !!! Help -_- please)
Solution:

spoiler
using UnityEngine;
using UnityEngine.Networking;

public class PlayerScrolWeapon : NetworkBehaviour
{
    public GameObject[] weapon;
    [SyncVar] int syncWeaponIndex;
    private int weaponIndex = 0;
  
    [Client]
  void FixedUpdate()
    {
        ScrolWeapon();
        if(isLocalPlayer)
            CmdSendToServerSyncWeapon(weaponIndex);
        SendToClientSyncWeapon();
  }

    void ScrolWeapon()
    {
        if(isLocalPlayer)
        {
            if(Input.GetAxisRaw("Mouse ScrollWheel") > 0f)
            {
                if (weaponIndex > 3)
                    weaponIndex = 0;
                else
                    weaponIndex++;
            }
            else if(Input.GetAxisRaw("Mouse ScrollWheel") < 0f)
            {
                if (weaponIndex < 0)
                    weaponIndex = 3;
                else
                    weaponIndex--;
            }

            for (int i = 0; i < 4; i++)
                if (i == weaponIndex)
                    weapon[i].SetActive(true);
                else
                    weapon[i].SetActive(false);
        }
    }

    void SendToClientSyncWeapon()
    {
        if(!isLocalPlayer)
        {
            for (int i = 0; i < 4; i++)
                if (i == syncWeaponIndex)
                    weapon[i].SetActive(true);
                else
                    weapon[i].SetActive(false);
        }
    }

    [Command]
    void CmdSendToServerSyncWeapon(int _weaponIndex)
    {
        syncWeaponIndex = _weaponIndex;
    }
}

This is 1 script that is responsible for changing weapons and for synchronizing it, maybe someone will come in handy.
PS Topic closed!

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question