ARCore и Photon Networking

Раздел, посвящённый Дополненной Реальности и Виртуальной Реальности

ARCore и Photon Networking

Сообщение FigeraldS 07 май 2021, 02:24

Всем привет! Очень нужна помощь с Unity ARCore и Photon (PUN2).

Сделал программу расстановки префабов мебели в комнате, всее работает. Захотелось реализовать сетевое взаимодействие.
С помощью PUN2 пользователи могут зайти в одну комнату. Делаю спавн объекта на сцене:
Синтаксис:
Используется csharp
PhotonNetwork.Instantiate(objToSpawn.name, hits[0].pose.position, objToSpawn.transform.rotation);
, где objToSpawn -- префаб объекта,
hits[0].pose.position - координаты, где стоит маркер для спавна объекта.
Но почему-то объект не создается. Повыводил координаты и данные -- никаких ошибок нет, имя префаба выводится, нет никаких exception'ов.
Помогите, пожалуйста.
FigeraldS
UNец
 
Сообщения: 16
Зарегистрирован: 25 апр 2020, 00:47

Re: ARCore и Photon Networking

Сообщение FigeraldS 07 май 2021, 03:56

Верхнее решил. Нужно было просто префабы закинуть в папку Resources. Но у меня есть еще проблема.

Проблемы с расположением. Объекты почему-то находятся в разных местах на разных устройствах. Может быть, просто из-за света или из-за размеров комнаты?
Может быть, лучше использовать «cloud anchors» или даже просто «anchors»?
Помогите, пожалуйста, спасибо.
FigeraldS
UNец
 
Сообщения: 16
Зарегистрирован: 25 апр 2020, 00:47

Re: ARCore и Photon Networking

Сообщение Alkos26Rus 07 май 2021, 14:50

FigeraldS писал(а):Верхнее решил. Нужно было просто префабы закинуть в папку Resources. Но у меня есть еще проблема.

Проблемы с расположением. Объекты почему-то находятся в разных местах на разных устройствах. Может быть, просто из-за света или из-за размеров комнаты?
Может быть, лучше использовать «cloud anchors» или даже просто «anchors»?
Помогите, пожалуйста, спасибо.

Синхронизация нужна, у клиентов объект просто создался на нулевой позиции и нулевом повороте
Аватара пользователя
Alkos26Rus
Адепт
 
Сообщения: 1642
Зарегистрирован: 26 ноя 2020, 17:52
Откуда: Москва

Re: ARCore и Photon Networking

Сообщение FigeraldS 07 май 2021, 18:10

Alkos26Rus писал(а):Синхронизация нужна, у клиентов объект просто создался на нулевой позиции и нулевом повороте


И правда, оъект в нуле. А как еще нужно синхронизировать положение? В примерах различных было, что нужно на каждого объекта наложить PhotonTransfrormView и поставить галочку у Position. https://wampi.ru/image/Rw8WlLO
FigeraldS
UNец
 
Сообщения: 16
Зарегистрирован: 25 апр 2020, 00:47

Re: ARCore и Photon Networking

Сообщение Alkos26Rus 07 май 2021, 21:25

FigeraldS писал(а):
Alkos26Rus писал(а):Синхронизация нужна, у клиентов объект просто создался на нулевой позиции и нулевом повороте


И правда, оъект в нуле. А как еще нужно синхронизировать положение? В примерах различных было, что нужно на каждого объекта наложить PhotonTransfrormView и поставить галочку у Position. https://wampi.ru/image/Rw8WlLO

Ну да можно и так, по разному можно. Можно с помощью OnPhotonSerializeView передавать 2 вектора (позиция, поворот), только в настройках PhotonView нужно поставить тип передачи On Change. Можно послать буферезированное сообщение [PunRPC] с позицией и поворотом, плюс в том что отправляется один раз, минус - при смене мастер клиента удаляется, нужно как то от имени комнаты посылать, не помню как, нужно доки смотреть.
Аватара пользователя
Alkos26Rus
Адепт
 
Сообщения: 1642
Зарегистрирован: 26 ноя 2020, 17:52
Откуда: Москва

Re: ARCore и Photon Networking

Сообщение FigeraldS 07 май 2021, 22:05

FigeraldS писал(а):В примерах различных было, что нужно на каждого объекта наложить PhotonTransfrormView и поставить галочку у Position. https://wampi.ru/image/Rw8WlLO
Через галочку не работает(

Alkos26Rus писал(а):Ну да можно и так, по разному можно. Можно с помощью OnPhotonSerializeView передавать 2 вектора (позиция, поворот), только в настройках PhotonView нужно поставить тип передачи On Change. Можно послать буферезированное сообщение [PunRPC] с позицией и поворотом, плюс в том что отправляется один раз, минус - при смене мастер клиента удаляется, нужно как то от имени комнаты посылать, не помню как, нужно доки смотреть.


Пробовал с OnPhotonSerializeView изменять цвет объекта. Правильно понимаю, что нужно создать скрипт, реализующий IPunObservable и на каждый объект, которые будет создаваться на сцене навесить его.
Синтаксис:
Используется csharp
public class PrefabController : MonoBehaviour, IPunObservable
{
    private int materialId;
    private Transform[] transformArray;
    [SerializeField]
    private GameObject prefab;

    public static PrefabController Instance
    {
        get; private set;
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        //Мы пишем данные
        if (stream.IsWriting)
        {
            stream.SendNext(materialId);
        }
        else //Иначе читаем.
        {
            materialId = (int)stream.ReceiveNext();
        }
    }

    // Start is called before the first frame update
    void Start()
    {
        Instance = this;
        transformArray = prefab.GetComponentsInChildren<Transform>();
    }

    // Update is called once per frame
    void Update()
    {
        if (HittedObj != null)
        {
            SetMaterial();
            HittedObj = null;
        }
    }

    public GameObject HittedObj { get; set; }

    /// <summary>
    /// Устанавливает материал на объект.
    /// </summary>
    public void SetMaterial() { //Устанавливает материал на объект }
}
 


HittedObj -- индекс Material, который ставлю в MeshRenderer, изменяю через другой скрипт, в котором на объект, на который тыкнули на сцене передается индекс материала.

Эта штука работает не обновляет данные для других пользователей, только для себя цвет меняется.
FigeraldS
UNец
 
Сообщения: 16
Зарегистрирован: 25 апр 2020, 00:47

Re: ARCore и Photon Networking

Сообщение Alkos26Rus 07 май 2021, 23:09

С чего ты взял что эта команда срабатывает у клиентов?
Синтаксис:
Используется csharp
        if (HittedObj != null)
        {
            SetMaterial();
            HittedObj = null;
        }
 


Тебе нужно разделять логику для влядельца объекта и у остальных клиентов. Есть такой параметр isMine в PhotonVew.

Не знаю что имеено у тебя не работает,но я обчыно использую 2 переменных для отслеживания изменений, например
Синтаксис:
Используется csharp
int current_mat_index;
int old_mat_index;

void Update(){
if(current_mat_index != old_mat_index)SetMatIndex();
}

void SetMatIndex(){
old_mat_index = current_mat_index ;
//меняем материал
}

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        //Мы пишем данные
        if (stream.IsWriting)
        {
            stream.SendNext(current_mat_index );
        }
        else //Иначе читаем.
        {
            current_mat_index = (int)stream.ReceiveNext();
       

 

Не знаю, может нужно как то по другому делать, но такой способ работает безотказно.
Аватара пользователя
Alkos26Rus
Адепт
 
Сообщения: 1642
Зарегистрирован: 26 ноя 2020, 17:52
Откуда: Москва

Re: ARCore и Photon Networking

Сообщение FigeraldS 08 май 2021, 01:31

Alkos26Rus писал(а):С чего ты взял что эта команда срабатывает у клиентов?
Синтаксис:
Используется csharp
        if (HittedObj != null)
        {
            SetMaterial();
            HittedObj = null;
        }
 


Тебе нужно разделять логику для влядельца объекта и у остальных клиентов. Есть такой параметр isMine в PhotonVew.


Как я понял, это работает у всех, если нет никакого привоения объектов, например, if(photonView.isMine).


Пометил метод [PunRPC] аннотацией. Цвет передается, но только один раз, иногда как будто индексы путаются.
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;

public class PrefabController : MonoBehaviour, IPunObservable
{
    private int materialId;

    private Transform[] transformArray;
    [SerializeField]
    private GameObject prefab;

    private PhotonView photonView;

    public static PrefabController Instance
    {
        get; private set;
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        //Мы пишем данные
        if (stream.IsWriting)
        {
            stream.SendNext(materialId);
        }
        else //Иначе читаем.
        {
            materialId = (int)stream.ReceiveNext();
        }
    }

    void Start()
    {
        photonView = prefab.GetComponent<PhotonView>();
        txt = GameObject.FindWithTag("Logger").GetComponent<Text>();
        txt.text += "PrefabController";
        Instance = this;
        transformArray = prefab.GetComponentsInChildren<Transform>();
    }

    void Update()
    {
        if (HittedObj != null)
        {
            //SetMaterial();
            photonView.RPC("SetMaterial", RpcTarget.All);
            //HittedObj = null;
        }
    }

    public GameObject HittedObj { get; set; }

    public Text txt;

    [PunRPC]
    public void SetMaterial()
    {
        txt.text += $"\n{prefab == null} and {HittedObj == null}\n";
        //if (HittedObj == prefab)
        //{
        foreach (var e in transformArray)
        {
            if (e.name.StartsWith("obj"))   //Equals.
            {
                e.GetComponent<MeshRenderer>().material = MaterialSetterButton.Material;
                Debug.Log(e.GetComponent<MeshRenderer>().materials[0] + " set");
            }
        }
        //}
    }
}
 


Пробовал c old и curr. Работает примерно также.
FigeraldS
UNец
 
Сообщения: 16
Зарегистрирован: 25 апр 2020, 00:47

Re: ARCore и Photon Networking

Сообщение Alkos26Rus 08 май 2021, 12:06

Пробовал c old и curr. Работает примерно также.

покажи как ты пробобовал, скорей всего ты делаешь все не правильно. Тебе нужно почитать доки по фотону или посмотреть тутореалы, как синхронизировать данные

Синтаксис:
Используется csharp
e.GetComponent<MeshRenderer>().material = MaterialSetterButton.Material;

Что за MaterialSetterButton и где я не вижу связанно materialId и MaterialSetterButton.Material, где ты назначаешь materialId? Выведи на экран значение materialId и ты увидишь, что либо он равен нулу на обоих устройсвах, либо он не равен нулю на обоих устройствах, что значит что ты не правильно назначаешь материал.
Аватара пользователя
Alkos26Rus
Адепт
 
Сообщения: 1642
Зарегистрирован: 26 ноя 2020, 17:52
Откуда: Москва

Re: ARCore и Photon Networking

Сообщение FigeraldS 10 май 2021, 23:52

Alkos26Rus писал(а):
Синтаксис:
Используется csharp
e.GetComponent<MeshRenderer>().material = MaterialSetterButton.Material;

Что за MaterialSetterButton и где я не вижу связанно materialId и MaterialSetterButton.Material, где ты назначаешь materialId? Выведи на экран значение materialId и ты увидишь, что либо он равен нулу на обоих устройсвах, либо он не равен нулю на обоих устройствах, что значит что ты не правильно назначаешь материал.


Да, запутался в своем же коде. Изменил его немного
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Photon.Pun;

public class PrefabController : MonoBehaviour, IPunObservable
{
    private static int materialId;

    public static int idset { get { return materialId; } set { materialId = value; } }

    private Transform[] transformArray;
    [SerializeField]
    private GameObject prefab;

    public static PrefabController Instance
    {
        get; private set;
    }

    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    {
        //Мы пишем данные
        if (stream.IsWriting)
        {
            stream.SendNext(materialId);
        }
        else //Иначе читаем.
        {
            materialId = (int)stream.ReceiveNext();
            txt.text = "read";
            txt.text += materialId + "\n";
        }
    }

    void Start()
    {
        materialSetterButton = MaterialSetterButton.Instance;
        txt = GameObject.FindWithTag("Logger").GetComponent<Text>();
        Instance = this;
    }

    void Update()
    {
        if (HittedObj != null && HittedObj.GetComponent<PhotonView>().IsMine)
        {
            transformArray = HittedObj.GetComponentsInChildren<Transform>();
            //HittedObj.GetComponent<PhotonView>().RPC("SetMaterial", RpcTarget.All);
        }
        if (HittedObj != null)
            SetMaterial();
    }

    public static GameObject HittedObj { get; set; }

    public Text txt;

    public void SetMaterial()
    {
        txt.text = $"\n{HittedObj.name}\n";

        foreach (var e in transformArray)
        {
            if (e.name.Equals("obj"))
            {
                try
                {
                    txt.text += "\n" + (idset) + " id";
                    //materialId = materialSetterButton.materialId;
                    e.GetComponent<MeshRenderer>().material = MaterialsColor.Instance[materialId];//MaterialSetterButton.Material;
                    Debug.Log(e.GetComponent<MeshRenderer>().materials[0] + " set");
                }
                catch (System.Exception ex)
                {
                    txt.text += ex.Message;
                }
            }
        }
    }
}
 

Теперь на экране второго устройства выводится правильный id, в блоке
Синтаксис:
Используется csharp
        else //Иначе читаем.
        {
            materialId = (int)stream.ReceiveNext();
            txt.text = "read";
            txt.text += materialId + "\n";
        }

но еще все равно не меняется материал на втором устройстве. Посмотрел видео и примеры синхронизации данных, вроде все верно делаю: если мой объект, то сохраняю его детей, чтобы сделать setMaterial().
FigeraldS
UNец
 
Сообщения: 16
Зарегистрирован: 25 апр 2020, 00:47


Вернуться в AR / VR

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1