forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Сеть (http://forum.boolean.name/forumdisplay.php?f=169)
-   -   Одна камера на двух мультиплеерах. (http://forum.boolean.name/showthread.php?t=19961)

daniladiv 26.08.2015 09:37

Одна камера на двух мультиплеерах.
 
Добрый день. Никак не получается сделать следующее: имеется клиент и сервер. Требуется чтобы можно было управлять одной камерой из сервера и из клиента. Пробовал на камеру ставить нетворктранформ но он работает только в одну сторону и то как то не правильно. Так же пробовал передавать через РПС но передает только координаты и поворот не передает.

pax 26.08.2015 12:19

Ответ: Одна камера на двух мультиплеерах.
 
А покажи свой код использования RPC, в котором не передает поворот.

daniladiv 26.08.2015 13:01

Ответ: Одна камера на двух мультиплеерах.
 
Код:

using UnityEngine;
using System.Collections;
//using UnityEngine.Networking;


public class GlVar : MonoBehaviour
{
    public int t;
    public GameObject Camera;
    //NetworkView networkView;
 
    public void SetPos()
    {
        this.GetComponent<NetworkView>().RPC("RSetPos", RPCMode.All, Camera.transform.position, Camera.transform.localRotation);
       
    }
    [RPC]
    void RSetPos(Vector3 pos, Quaternion rot)
    {
        print((pos.x).ToString());
        Camera.transform.position = pos;
        Camera.transform.localRotation = rot;
    }
}

В данном коде положение правильно передает. Я пока временно пробую вызывать эту функцию через кнопку. Во время нажатия на другом клиенте мигает нужный поворот и исчезает а положение нормально устанавливается.
Этот скрипт положен на пустой ГО и повесил нетворквие.
public GameObject Camera - летающая камера которой управляет клиент.

У меня юнити 5, хотел сделать чкркз нетворкпозитион но результат тот же что и сейчас.

pax 26.08.2015 13:07

Ответ: Одна камера на двух мультиплеерах.
 
Ну RPCMode.All это перебор. Надо RPCMode.Server. Кроме того, надо передавать серверу не положение камеры и ее вращение, а информацию о вводе с клавиатуры и мыши. Например оси Vertical/Horizontal/Mouse X/Mouse Y.

На сервере обрабатывать эти данные, применять к камере трансформации, а потом с помощью NetworkView и Transform передавать всем координаты камеры и ее вращение. Например через другой RPC с RPCMode.Others.

daniladiv 26.08.2015 13:15

Ответ: Одна камера на двух мультиплеерах.
 
То есть отсылать серверу какую именно клавишу нажали а на сервере вызывать специальную функцию которая имитирует нажатие данной клавиши? Или как?

daniladiv 26.08.2015 14:43

Ответ: Одна камера на двух мультиплеерах.
 
Сделал так
Код:

using UnityEngine;
using System.Collections;
//using UnityEngine.Networking;


public class GlVar : MonoBehaviour
{
    public int t;
    public GameObject Camera;
    NetworkView networkView;
    private Vector3 transfer;
    public bool ClientCon;
    public bool iServ;
    float rotationX = 0F;
    float rotationY = 0F;
    float mouseSensitivity = 3.0f;
    float minimumX = -360F;
    float maximumX = 360F;
    float minimumY = -60F;
    float maximumY = 60F;
    Quaternion originalRotation;

    void Update()
    {
        if (ClientCon && (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0 || Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0))
        {
            SetPos2();
        }
    }

    //-----------------------------------------
    public void SetPos2()
    {
        float V = Input.GetAxis("Vertical");
        float H = Input.GetAxis("Horizontal");
        float X = Input.GetAxis("Mouse X");
        float Y = Input.GetAxis("Mouse Y");
        this.GetComponent<NetworkView>().RPC("SetKey", RPCMode.All, V, H, X, Y);
    }

    [RPC]
    void SetKey(float V, float H, float X, float Y)
    {
        // Движения мыши -> Вращение камеры
        rotationX += X * mouseSensitivity;
        rotationY += Y * mouseSensitivity;
        rotationX = ClampAngle(rotationX, minimumX, maximumX);
        rotationY = ClampAngle(rotationY, minimumY, maximumY);
        Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
        Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, Vector3.left);
        Camera.transform.rotation = originalRotation * xQuaternion * yQuaternion;
        // перемещение камеры
        transfer = transform.forward * V;
        transfer += transform.right * H;
        transform.position += transfer * 2 * Time.deltaTime;
        Camera.transform.position += transfer * 2 * Time.deltaTime;
        print("V="+V.ToString());
    }
    public static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360F) angle += 360F;
        if (angle > 360F) angle -= 360F;
        return Mathf.Clamp(angle, min, max);
    }


}

Не работает. Не пойму почему?

pax 26.08.2015 15:32

Ответ: Одна камера на двух мультиплеерах.
 
Ну ты отсылаешь управление каждый кадр, довольно часто на самом деле, попробуй его отсылать хотя бы в FixedUpdate. Потом тут в сприпте нет отправки положения и вращения всем остальным. NetworkView настроен на трансформ? И опять же RPCMode.Server надо

daniladiv 26.08.2015 16:07

Ответ: Одна камера на двух мультиплеерах.
 
FixedUpdate - сделал.
NetworkView настроен на трансформ? - Да и на меню для подключения и там где правлю данный скрипт.
RPCMode.All - это пока временно, потом сделаю условие какой клиент сможет смотреть и управлять камерой другого клиента. Пока делаю между сервером и клиентом.
Вроде все правильно я понимаю?
То что это в апдате лежит там тоже будет потом код на проверку для какого клиента нужно вызывать.
Почему позиция нормально работает если закоментить
Код:

        // Движения мыши -> Вращение камеры
        rotationX += X * mouseSensitivity;
        rotationY += Y * mouseSensitivity;
        rotationX = ClampAngle(rotationX, minimumX, maximumX);
        rotationY = ClampAngle(rotationY, minimumY, maximumY);
        Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
        Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, Vector3.left);
        Camera.transform.rotation = originalRotation * xQuaternion * yQuaternion;

Изменил код и стал лучше двигаться. Как дело с углом поборть?
Код:

    public void SetPos()
    {
        Vector3 p = Camera.transform.position;
        this.GetComponent<NetworkView>().RPC("SetKey", RPCMode.All, p);
    }

    [RPC]
    void SetKey(Vector3 pos)
    {
        // Движения мыши -> Вращение камеры
      /* rotationX += X * mouseSensitivity;
        rotationY += Y * mouseSensitivity;
        rotationX = ClampAngle(rotationX, minimumX, maximumX);
        rotationY = ClampAngle(rotationY, minimumY, maximumY);
        Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
        Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, Vector3.left);
        Camera.transform.rotation = originalRotation * xQuaternion * yQuaternion;*/
       
        // перемещение камеры
        Camera.transform.position = pos;

    }


daniladiv 26.08.2015 16:50

Ответ: Одна камера на двух мультиплеерах.
 
Поворот как бы сбрасывается, не хочет устанавливаться.

pax 26.08.2015 17:21

Ответ: Одна камера на двух мультиплеерах.
 
Оно у тебя и не работает видимо. Переменная Y непонятно откуда берется. Еще у тебя сервер сам себе управление шлет. Возможно он и сбрасывает.

daniladiv 27.08.2015 09:46

Ответ: Одна камера на двух мультиплеерах.
 
Упростил код но все равно поворот не хочет устанавливаться, он мелькнет на пару долесекунд и сброситься. Перемещение камеры работает хорошо.
Код:

using UnityEngine;
using System.Collections;


public class GlVar : MonoBehaviour
{
    public GameObject Camera; // единственная камера на сцене
    public bool iClient; //выставляются в другом скрипте правильно
    public bool iServ;

    void Update()
    {
        if ((Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0
            || Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0))
        {         
            SetPos();
        }
    }

    public void SetPos()
    {
        Vector3 p = Camera.transform.position;
        Vector3 r = Camera.transform.eulerAngles;
        if (iClient)// я клиент
        this.GetComponent<NetworkView>().RPC("SetKey", RPCMode.Server, p, r);
        if (iServ) // я сервер
        this.GetComponent<NetworkView>().RPC("SetKey", RPCMode.Others, p, r);
    }

    [RPC]
    void SetKey(Vector3 pos, Vector3 r)
    {
            // Движения мыши -> Вращение камеры
            Camera.transform.eulerAngles = r;
            // перемещение камеры
            Camera.transform.position = pos;   
    }

}

Сбрасывает скрипт управления камерой
Код:

using UnityEngine;
using System.Collections;
//using UnityEngine.Networking;

public class Polet : MonoBehaviour
{

    public float mouseSensitivity = 3.0f;
    public float speed = 2.0f;
    private Vector3 transfer;
    private GameObject globalvar;
   
    public float minimumX = -360F;
    public float maximumX = 360F;
    public float minimumY = -60F;
    public float maximumY = 60F;
    float rotationX = 0F;
    float rotationY = 0F;
    Quaternion originalRotation;

    public float X;

    void Awake()
    {
        GetComponent<Camera>().orthographic = false;
    }

    void Start()
    {
        originalRotation = transform.rotation;
        globalvar = GameObject.Find("GV");

    }

    void Update()
    {
        // Движения мыши -> Вращение камеры
        rotationX += Input.GetAxis("Mouse X") * mouseSensitivity;
        rotationY += Input.GetAxis("Mouse Y") * mouseSensitivity;
        rotationX = ClampAngle(rotationX, minimumX, maximumX);
        rotationY = ClampAngle(rotationY, minimumY, maximumY);
        Quaternion xQuaternion = Quaternion.AngleAxis(rotationX, Vector3.up);
        Quaternion yQuaternion = Quaternion.AngleAxis(rotationY, Vector3.left);
        transform.rotation = originalRotation * xQuaternion * yQuaternion;
        // перемещение камеры
        transfer = transform.forward * Input.GetAxis("Vertical");
        transfer += transform.right * Input.GetAxis("Horizontal");
        transform.position += transfer * speed * Time.deltaTime;
        //
        X = Input.GetAxis("Mouse X");

    }

    public static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360F) angle += 360F;
        if (angle > 360F) angle -= 360F;
        return Mathf.Clamp(angle, min, max);
    }

}

Как поступить? Отключать скрипт если игрок не нажимает кнопки и не двигает мышью?


Часовой пояс GMT +4, время: 17:22.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot