Unity3D странное поведение камер в мультиплеере - PullRequest
0 голосов
/ 23 января 2020

я новичок в единстве и борюсь со странным поведением моих камер. Я программирую многопользовательскую онлайн-игру с помощью плагина Photon.

Странное поведение:

  • Player1 входит в систему

    -> все хорошо

  • Player2 входит в систему

    -> Камера Player1 переключается на персонажа Player2

    -> Камера Player2 переключается на персонажа Player1

  • Player3 входит в систему

    -> Камера Player 1 и Player2 переключается на персонажа Player3

    -> Камера Player3 переключается на персонажа Player2.

(но управление движением работает правильно для каждого игрока)

Я получил префаб персонажа, которому в инспекторе прикреплена камера.

А вот мой код для инициализации:

public class NetworkPlayer  : Photon.Pun.MonoBehaviourPun, Photon.Pun.IPunObservable
{
    public Animator anim;
    private Vector3 correctPlayerPos;
    private Quaternion correctPlayerRot;
    public GameObject myCam;
    // Start is called before the first frame update
    void Start()
    {
        if(photonView.IsMine)
        {
            Debug.Log("PhotonView.IsMine == true");
            //Kamera und Steuerung aktivieren
            myCam = GameObject.Find("Camera");
            myCam.SetActive(true);
            GetComponent<PlayerMovement>().enabled = true;
            Debug.Log("Steuerung und Cam aktiviert...");
        }
    }

    // Update is called once per frame
    void Update()
    {
        if(!photonView.IsMine)
        {
            transform.position = Vector3.Lerp(transform.position, this.correctPlayerPos, Time.deltaTime*5);
            transform.rotation = Quaternion.Lerp(transform.rotation, this.correctPlayerRot, Time.deltaTime * 5);
        }
    }

    //Exchange Position data
    public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info){
        if(stream.IsWriting)
        {
            //Send data to others
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);
            stream.SendNext(anim.GetBool("Run"));
        } 
        else 
        {
            //Receive data from others
            this.correctPlayerPos = (Vector3) stream.ReceiveNext();
            this.correctPlayerRot = (Quaternion) stream.ReceiveNext();
            anim.SetBool("Run", (bool) stream.ReceiveNext());
        }
    }
}

Я также пытался подключить камеру через инспектор, а не искать ее, как в примере кода выше. Надеюсь, что кто-нибудь может мне помочь с этим: (

Спасибо за ваше время!

1 Ответ

1 голос
/ 23 января 2020

Я полагаю, что вы делаете SetAtive(true) на плеере, но по вашему изображению камера все равно активна по умолчанию! Таким образом, каждая новая камера добавляется ниже предыдущих в иерархии, что делает ее камерой, отрисованной сверху.

Вы можете просто отключить Camera в префабе плеера.

В любом случае вам следует также активно отключите камеру для других игроков в сценарии, чтобы вы не могли забыть / не должны полагаться на установку своего префаба в определенное состояние

public class NetworkPlayer  : Photon.Pun.MonoBehaviourPun, Photon.Pun.IPunObservable
{
    public Animator anim;
    // you are referncing this for the prefab via the inspector
    // I would also use the proper type as a safety
    // this way you can't by accident reference something else here but a Camera
    public Camera myCam;

    // you should also this already via the inspector
    public PlayerMovement playerMovement;

    private Vector3 correctPlayerPos;
    private Quaternion correctPlayerRot;

    // Use Awake to gather components and references as fallback
    // if they where not referenced via the Inspector
    private void Awake()
    {
        FetchComponents();
    } 

    // Fetches components only if they where not referenced via the Inspector
    // this saves unnecessary GetComponent calls which are quite expensive
    //
    // + personal pro tip: By using the context menu you can now also in the Inspector simply click on FetchComponents
    // This way you 
    //   a) don't have to search and drag them in manually
    //   b) can already see if it would also work later on runtime 
    [ContextMenu(nameof(FetchComponents))]
    private void FetchComponents()
    {
        if(!playerMovement) playerMovement = GetComponent<PlayerMovement>();
        if(!anim) anim = GetComponent<Animator>();
        // Use GetComponnetInChildren to retrieve the component on yourself
        // or recursive any of your children!
        // Pass true in order to also get disabled or inactive ones
        if(!myCam) myCam = GetComponentInChildren<Camera>(true);
    }       

    // Now do your thing not only for the player but also actively disable the stuff
    // on all other players
    private void Start()
    {
        var isMine = photonView.IsMine;
        Debug.Log($"PhotonView.IsMine == {isMine}");
        // enable the cam for you, disable them for others!
        myCam.gameObject.SetActive(isMine);
        // enable controls for you, disable them for others
        playerMovement.enabled = isMine;

        Debug.Log($"Steuerung und Cam {isMine ? "" : "de"}aktiviert...");
    }

    ...
}
...