Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Unet camara independiente por tag

Iniciado por brok, Diciembre 28, 2017, 10:50:53 AM

Tema anterior - Siguiente tema
Hola, estoy intentando hacer un juego online de coches y no doy con la manera de que cuando inicia el cliente local del server local, se vincule al player del cliente al tag se queda en el del server.
 
Este es el código que utilizo para vincular la cámara no se si es lo correcto alguien podría orientarme.
 

if (!isLocalPlayer)
        {
            try
            {
                Car1 = GameObject.FindGameObjectWithTag("Player").transform;
            }
            catch (NullReferenceException)
            {
                Debug.Log("Car1 ecocntrado");
            }
        }
        else
        {
            try
            {
                Car1 = GameObject.FindGameObjectWithTag("Player").transform;
            }
            catch (NullReferenceException)
            {
                Debug.Log("Car1 ecocntrado");
            }
        }

 
 

Diciembre 28, 2017, 11:01:14 AM #1 Ultima modificación: Diciembre 28, 2017, 11:04:08 AM por brok
Cita de: gZone date=1514455167¿?
   


si se queda en el tag Player del server el del cliente.
 

Cita de: gZone date=1514459000Sigo sin descifrar lo que tratas de decir (debo tener un día espeso)...
   
   
      ...la cámara solo la tienes que asignar cuando el player es local (isLocalPlayer es true).
   
   
      * en el código que muestras lo que haces es asignar el coche tanto para true como para false... y no se muestra como asignas la cámara.
   


Sera que estoy confundido mira este el código de la cámara.
 

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class CamaraCar1 : NetworkBehaviour
{
    private Transform Car1;
    public float Suavizado = 10f;
   
   
    void Update()
    {
        if (!isLocalPlayer)
        {
            try
            {
                Car1 = GameObject.FindGameObjectWithTag("Player").transform;
            }
            catch (NullReferenceException)
            {
                Debug.Log("Car1 ecocntrado");
            }
        }
        else
        {
            try
            {
                Car1 = GameObject.FindGameObjectWithTag("Player").transform;
            }
            catch (NullReferenceException)
            {
                Debug.Log("Car1 ecocntrado");
            }
        }
       
    }
    void FixedUpdate()
    {
        if (Car1 != null)
        {
           
            transform.position = Vector3.Lerp(transform.position, Car1.position, Suavizado * Time.fixedDeltaTime);
            transform.rotation = Quaternion.Lerp(transform.rotation, Car1.rotation, Suavizado * Time.fixedDeltaTime);
           
        }
       
    }
 
}

 
 
 
me funciona bien pero solo al player del server y como ves en la imagen el cliente tiene la misma visión.
 
Con este código instancion las camras.
 

using UnityEngine.Networking;
public class RedManagerPosicionCamara : NetworkBehaviour {
    public Transform posicionInicial;
   
    public GameObject Camara1;
    public GameObject Camara2;
    // Use this for initialization
    void Start ()
    {
       
       
        if (!isLocalPlayer)
        {
            Camara1 = Instantiate(Camara1);
            Camara2 = Instantiate(Camara2);
            NetworkManager.RegisterStartPosition(posicionInicial);
            return;
        }
    }


}

 
 
 

Pero entonces solo hay una cámara para todos los players, porque yo lo he intentado con una y no funciona tampoco.
Ya lo he intentado con una y pasa lo mismo.

Yo lo que quiero hacer es primero trabajar en local con localhost mi pc y luego ya aprender tenga el proyecto mas avanzado hacerlo online, me entiendes

Diciembre 28, 2017, 04:46:15 PM #4 Ultima modificación: Diciembre 28, 2017, 04:48:04 PM por brok
Cita de: gZone date=1514475887Confundes la lógica multiplayer...
   
   
      ¿has realizado los tutoriales de UNet?
   
   
       
   


Si porque no lo a ver entendido bien pero de todas formas hay no sale lo que quiero hacer.

Cita de: gZone date=1514475887Confundes la lógica multiplayer...
   
   
      ¿has realizado los tutoriales de UNet?
   
   
       
   


Exactamente! lo que vengo repitiendo a muchos usuarios del foro, UNET no te facilita nada, mas bien te puede llegar hasta complicar las cosas si no entendes como funcionan los socket la serialización, etc ... Todo el apartado de redes es importante -
 
Un juego multijugador no cambia su estructura cuando pasamos de Single a Multi, simplemente cambia el GamePlay - si por ejemplo en tu juego tienes un GameManager con singleton este puede ser usado por el usuario local - pero los usuarios remotos no tienen interacción con los datos locales, es el servidor quien se encarga de todo esto -
 
Para las cámaras, simplemente deja la main camera, y colocas el componente para seguir el target
 

public class CameraCAR : MonoBehaviour
{
public static CameraCAR singleton { get; private set; }
private Transform _target = null;
private void Awake()
    {
   singleton = this;
    }
private void LateUpdate()
    {
   if(_target != null)   
      //Move Cam
    }
public void SetTarget(Transform target)
    {
   _target = target;
    }
}

 
Luego desde el Componente NetworkBehaviour que controla el Cliente seteas el target desde la función virtual OnStartLocalPlayer();
 

public class UNETPlayer : MonoBehaviour
{
public override void OnStartLocalPlayer()
    {
   CameraCAR.SetTarget(Transoform del Objecto del Auto);
    }
}

 
 

Ya vine de vuelta con lo que me dice francoe1 y hace lo mismo.

Diciembre 28, 2017, 10:47:56 PM #7 Ultima modificación: Diciembre 31, 2017, 06:14:02 PM por pioj



   
      NullReferenceException: Object reference not set to an instance of an object
      PlayerID.OnStartLocalPlayer () (at Assets/script/PlayerID.cs:18)
      UnityEngine.Networking.NetworkIdentity.SetLocalPlayer (Int16 localPlayerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:781)
      UnityEngine.Networking.NetworkServer.SetupLocalPlayerForConnection (UnityEngine.Networking.NetworkConnection conn, UnityEngine.Networking.NetworkIdentity uv, UnityEngine.Networking.PlayerController newPlayerController) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1007)
      UnityEngine.Networking.NetworkServer.InternalAddPlayerForConnection (UnityEngine.Networking.NetworkConnection conn, UnityEngine.GameObject playerGameObject, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:946)
      UnityEngine.Networking.NetworkServer.AddPlayerForConnection (UnityEngine.Networking.NetworkConnection conn, UnityEngine.GameObject player, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:909)
      UnityEngine.Networking.NetworkManager.OnServerAddPlayerInternal (UnityEngine.Networking.NetworkConnection conn, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:1063)
      UnityEngine.Networking.NetworkManager.OnServerAddPlayer (UnityEngine.Networking.NetworkConnection conn, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:1029)
      UnityEngine.Networking.NetworkManager.OnServerAddPlayerMessageInternal (UnityEngine.Networking.NetworkMessage netMsg) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:879)
      UnityEngine.Networking.NetworkConnection.InvokeHandler (Int16 msgType, UnityEngine.Networking.NetworkReader reader, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:220)
      UnityEngine.Networking.NetworkServer.InvokeHandlerOnServer (UnityEngine.Networking.ULocalConnectionToServer conn, Int16 msgType, UnityEngine.Networking.MessageBase msg, Int32 channelId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkServer.cs:1654)
      UnityEngine.Networking.ULocalConnectionToServer.Send (Int16 msgType, UnityEngine.Networking.MessageBase msg) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/LocalConnections.cs:83)
      UnityEngine.Networking.ClientScene.AddPlayer (UnityEngine.Networking.NetworkConnection readyConn, Int16 playerControllerId, UnityEngine.Networking.MessageBase extraMessage) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:200)
      UnityEngine.Networking.ClientScene.AddPlayer (UnityEngine.Networking.NetworkConnection readyConn, Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:133)
      UnityEngine.Networking.ClientScene.AddPlayer (Int16 playerControllerId) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/ClientScene.cs:127)
      UnityEngine.Networking.NetworkManager.OnClientConnect (UnityEngine.Networking.NetworkConnection conn) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:1124)
      UnityEngine.Networking.NetworkManager.OnClientConnectInternal (UnityEngine.Networking.NetworkMessage netMsg) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkManager.cs:929)
      UnityEngine.Networking.NetworkConnection.InvokeHandler (UnityEngine.Networking.NetworkMessage netMsg) (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkConnection.cs:231)
      UnityEngine.Networking.LocalClient.ProcessInternalMessages () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/LocalClient.cs:141)
      UnityEngine.Networking.LocalClient.Update () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/LocalClient.cs:69)
      UnityEngine.Networking.NetworkClient.UpdateClients () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkClient.cs:965)
      UnityEngine.Networking.NetworkIdentity.UNetStaticUpdate () (at C:/buildslave/unity/build/Extensions/Networking/Runtime/NetworkIdentity.cs:1092)
   

[/quote]
 

 
 
Me Manda este error otra vez como en el script de la cámara pero el script de la cámara funcionaba, lo encuentra y con el try catch quitaba la NullRefer.
 
Ahora tengo 2 problemas mas estoy igual.
 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class PlayerID : NetworkBehaviour {
    [SyncVar]
    private string IdentidadNombrePlayer;
    private NetworkInstanceId PlayerNetID;
    private Transform Player;
     
    public override void OnStartLocalPlayer()
    {
        GetIdentidad();
        SetIdentidad();
       
        Camera.main.GetComponent<CamaraCar1>().SetTarget(GameObject.FindGameObjectWithTag("Player").transform);
       
    }
    private void Awake()
    {
        Player = transform;
    }
    private void Update()
    {
        if(Player.name == "" || Player.name == "Player(Clone)")
        {
            SetIdentidad();
           
        }
    }
    [Client]
    private void GetIdentidad()
    {
        PlayerNetID = GetComponent<NetworkIdentity>().netId;
        CmdServerMiIdentidad(CrearUnicoIdentidad());
    }
   
    private void SetIdentidad()
    {
        if (!isLocalPlayer)
        {
            Player.name = IdentidadNombrePlayer;
           
        }
        else
        {
            Player.name = CrearUnicoIdentidad();
        }
    }
    private string CrearUnicoIdentidad()
    {
        string UnicoNombre = "Player" + PlayerNetID.ToString();
        return UnicoNombre;
    }
    [Command]
    private void CmdServerMiIdentidad(string Nombre)
    {
        IdentidadNombrePlayer = Nombre;
    }
   
}

 
 
 
el el scipt de la camara el set target tengo puesto esto.
 

public void SetTarget(Transform target)
    {
        Car1 = target;
    }

 
 
 
Ahora fuciona perfecto he puesto esto, pero sigo con el mismo problema de que se ve la vista de la cámara del cliente como la del server.
 

    

public override void OnStartLocalPlayer()
    {
        GetIdentidad();
        SetIdentidad();
       
       CamaraCar1.singleton.SetTarget(GameObject.FindGameObjectWithTag("Player").transform);
       
    }


    

 

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
public class CamaraCar1 : NetworkBehaviour
{
    private Transform Car1 = null;
    public float Suavizado = 10f;
    public static CamaraCar1 singleton { get; private set; }
   
    private void Awake()
    {
        singleton = this;
    }
    void FixedUpdate()
    {
        if (Car1 != null)
        {
           
            transform.position = Vector3.Lerp(transform.position, Car1.position, Suavizado * Time.fixedDeltaTime);
            transform.rotation = Quaternion.Lerp(transform.rotation, Car1.rotation, Suavizado * Time.fixedDeltaTime);
           
        }
       
    }
 
    public void SetTarget(Transform target)
    {
        Car1 = target;
    }
}

 
 

Una pregunta si al meter la cámara en el prefab se duplica la cámara y funciona perfecto, ¿por ue con el tag no funciona. 

Cita de: gZone date=1514485897No creo que UNet tenga toda la culpa... el problema es que se confunde en lo más básico, no entiende la lógica.
   
   
       
   
   
       
   
   
      Haz lo que te indica @francoe1...
   
   
      Cliente/servidor y local/no local...
   
   
      Todos los clientes son locales (en su juego) y al mismo tiempo no locales (en el juego del rival).
   
   
      Básicamente se trata de tener una única cámara...
   
   
      ...y cuando tengas al player local en escena haces que la cámara lo siga. No hay más.
   


@gZone No le hecho la culpa a UNET
 
Lo que hace UNET que puede confundir a las personas es una conexión "diferente" por NetworkBehaviour, por ejemplo en los RPC como el siguiente ejemplo 

 
 

[Command]
private void Cmd_move(Vector3 input)
{
 Rpc_move(transform.position);
}
[ClientRPC]
private void Rpc_move(Vector3 pos)
{
 if(!isLocalPlayer)
transform.position = pos;
}

 
Si llamas la función Cmd esta se ejecutara en el servidor y el servidor llamara a Rpc_move en todos los objetos remotos -
 
Internamente el Jugador local envía un paquete etiquetado con su NetworkID + El nombre de la función + Los valores de parámetros serializados mediante Network Writer clase que trabaja junto con un MemoryStream para armar un conjuntos de bytes por último se cierra con un EOF y los bytes son enviados al servidor, el servidor lo recibe y busca el NetworkBehaviour con el ID del paquete, para facilitar estas cosas UNET crea un Diccionario con NetworkID como KEY y NetworkBehaviour como valor, una vez encontrado llama la función, si se hace una llamada de RPC dentro del Comando, UNET envia un paquete similar a a todos los clientes conectados.
 
Entendiendo esto se puede llegar a empezar a armar algo, pero por esta estructura UNET es muy confuso a veces -
 

 Camera.main.GetComponent<CamaraCar1>().SetTarget(GameObject.FindGameObjectWithTag("Player").transform);

 
¿Por qué buscas por TAG?, el problema es que cuando hay más de un jugador el FindGameObjectWithTag seleccionará el primero en la lista, esto es un error de diseño, ¿La variable Player esta asignada? ¿por qué no utilizar esta como target?, por otro lado, CamaraCar1 cuenta con un singleton esto sirve para que no tengas que hacer un GetComponent sobre un objeto que puede ser nulo.
 

public Transform PlayerModel;
public override void OnStartLocalPlayer()
{
CameraCar1.singleton.SetTarget(PlayerModel);
}

 
 

Muchas gracias francoe1 me has salvado funciona mil gracias, toda una buena explicación.

Si tienes razón llevo 4 días con esto del Unet


Hola de nuevo sigo con un problemilla he puesto esto:
 

public override void OnStartServer()
    {
        GetIdentidad();
        SetIdentidad();
        CamaraCar1.singleton.SetTarget(PlayerTarget);
    }

 
Me debe funcionar al copilar el server pero no funciona la cámara lo estoy haciendo bien. ¿O es que me falta otra cosa en otro lado? .


Etiquetas: