Проблема с мультиплеером

Общие вопросы о Unity3D

Проблема с мультиплеером

Сообщение Prodducer 30 ноя 2018, 16:43

Здравствуйте, возникла следующая проблема. Есть сцена, на которой расположен объект, который по нажатию какой либо кнопки, каким либо игроком, увеличивается в размере. Сделал скрипт, который повесил на этот объект, в котором на данный момент содержится только [SyncVar] переменная, отвечающая за текущий размер и перегруженная функция OnStartClient, в которой размер этого объекта обновляется для каждого зашедшего на сервер игрока. Но вот как осуществить функцию которая вызывалась бы у всех клиентов, подключенных к серверу. Немного пошарив в интернете понял, что чтобы клиент мог вызвать функцию у всех остальных клиентов, нужно сначала использовать [Command] функцию, которая будет вызывать [ClientRpc] функцию, но куда бы я ни пытался запихать эти функции (в скрипт самого объекта и скрипт игрока), либо увеличение происходит только на сервере, либо при попытке увеличить размер клиентом, выдает предупреждение "Trying to send command for object without authority".
Prodducer
UNец
 
Сообщения: 4
Зарегистрирован: 29 дек 2017, 15:46

Re: Проблема с мультиплеером

Сообщение KanycTa 30 ноя 2018, 19:40

Тут же всё просто!

Синтаксис:
Используется csharp
[SyncVar(hook="OnUpdatedByte")]
public byte e;

private void OnUpdatedByte(byte a)
{
print("Variable e updated...");
}

[Command]
private void CmdUserCommand(byte[] a){
RpcAcceptUserCommand(a);//вызываем у всех клиентов
TargetAcceptUserCommand(connectionToClient,a);//вызываем метод у конкретного соединения (клиента)
}

[ClientRpc]
private void RpcAcceptUserCommand(byte[] a){
print("received from server");
}

[TargetRpc]
private void TargetAcceptUserCommand(NetworkConnection c, byte[] a){
print("received from server");
}
 



Писал по памяти возможно что-то не так...
Аватара пользователя
KanycTa
UNIт
 
Сообщения: 107
Зарегистрирован: 25 июл 2018, 18:41
Откуда: г. Ульяновск
  • Сайт

Re: Проблема с мультиплеером

Сообщение Prodducer 30 ноя 2018, 20:34

Очень полезно, спасибо. Но проблема не совсем в непонимании кода, скорее в том что и откуда должно вызываться. Распишу более подробно:
Вот фрагмент кода из скрипта Player:
Синтаксис:
Используется csharp
private void Update()
    {
        if (!isLocalPlayer)
            return;

        RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.forward, out hit, 4f))
        {
            if (hit.collider.tag == "Tree")
                if (Input.GetButtonDown("Submit"))
                    hit.collider.GetComponent<MultiplayerTree>().CmdGrow();
        }
    }

А вот код из скрипта Tree:
Синтаксис:
Используется csharp
public class MultiplayerTree : NetworkBehaviour {

    [SyncVar]
    public int curSize = 1;

    public override void OnStartClient()
    {
        base.OnStartClient();
        transform.localScale = Vector3.one * curSize;
    }

    [Command]
    public void CmdGrow()
    {
        RpcUpdateSize();
    }

    [ClientRpc]
    public void RpcUpdateSize()
    {
        curSize++;
        transform.localScale = Vector3.one * curSize;
        if (curSize == 10)
        {
            print("You won!");
        }
    }
}

При таком раскладе, когда клиент пытается вызвать эту функцию, выдает предупреждение, о котором я писал выше.

Также я думал о том, чтобы [Command] функцию вызывать в самом игроке, и из нее вызывать [ClientRpc] функцию в объекте. Но в таком случае мне нужно передать hit.collider.GetComponent<MulitplayerTree>() в [Command] функцию(чтобы знать какой объект должен увеличить размер), но здесь мне уже говорят, что нельзя передавать аргумент в [Command] функцию.
Prodducer
UNец
 
Сообщения: 4
Зарегистрирован: 29 дек 2017, 15:46

Re: Проблема с мультиплеером

Сообщение KanycTa 30 ноя 2018, 20:46

Prodducer писал(а):"Trying to send command for object without authority".


Нельзя так делать, нужно чтобы на объекте где вызывается [Command] на NetworkIdentity должна стоять галочка Local Player Authority, я точно не помню... Вроде бы нельзя таким способом отправлять команды...

Чтобы иметь возможность отправлять команды, объект где применяется атрибут [Command] должен быть игроком т.е. быть привязаным к NetworkConnection (соединению клиента)...

Есть решение: Делать рейкаст на стороне сервера (хоста)


UPD:

Можно и не делать вызов процедуры на клиентах а повесит на SyncVar хук!


Синтаксис:
Используется csharp
[SyncVar(hook="OnReceivedCurSize")]
private Vector3 curSize;
private void OnReceivedCurSize(Vector3 vec3)
{
}
 


OnReceivedCurSize - будет вызываться при изменении значения переменной помеченной как SyncVar
Аватара пользователя
KanycTa
UNIт
 
Сообщения: 107
Зарегистрирован: 25 июл 2018, 18:41
Откуда: г. Ульяновск
  • Сайт

Re: Проблема с мультиплеером

Сообщение Prodducer 03 дек 2018, 08:12

Решил проблему путем рейкаста на стороне хоста. Большое спасибо за помощь!
Prodducer
UNец
 
Сообщения: 4
Зарегистрирован: 29 дек 2017, 15:46


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 11