如何为 Photon 中的玩家初始化摄像头

7

我正在制作2D游戏,问题在于当第一个玩家创建并出现在房间中时,他的摄像机正常工作,但当新玩家进入房间后,第一个玩家通过第二个玩家的摄像机看到了一切。此外,如果第三个玩家连接,第一个和第二个玩家将通过第三个玩家的摄像机看到所有内容,以此类推。

玩家预制体实例化在GameManager类中,该类仅存在于游戏场景中。

public class GameManager : MonoBehaviourPunCallbacks
    {
        public GameObject playerPrefab;
        public Transform spawnPoint;

        public void Start()
        {
            GameObject player = PhotonNetwork.Instantiate(this.playerPrefab.name, spawnPoint.position, Quaternion.identity);
            player.GetComponent<FireFighterHeroController>().enabled = true;
            player.GetComponent<CameraControler>().enabled = true;
            player.GetComponent<CameraControler>().SetTarget(player.transform);
        }

        #region PUN Callbacks

        public override void OnLeftRoom()
        {
            SceneManager.LoadScene(1);
        }

        #endregion

        #region Custom Methods

        public void OnClickLeaveRoom_Btn()
        {
            PhotonNetwork.LeaveRoom();
        }

        #endregion
}

简单的照相机控制器
public class CameraControler : MonoBehaviour
    {
        private Transform target;
        public GameObject camera;
        public Vector3 offset;

        public void SetTarget(Transform target)
        {
            this.target = target;
        }

        public void LateUpdate()
        {
            camera.transform.position = target.position + offset;
        }
    }

更新:找到了解决方法

我将摄像机控制器的脚本移动到了玩家的摄像机上,然后在玩家实例中搜索这个摄像机,开启它并将玩家的变换传递给它。

不确定这种方法是否可行,但至少可以工作。

这就是那只“怪兽”。

public class GameManager : MonoBehaviourPunCallbacks
    {
        public Transform spawnPoint;

        public void Start()
        {
            GameObject player = PhotonNetwork.Instantiate("Player", spawnPoint.position, Quaternion.identity);

            if (!player.GetPhotonView().IsMine)
                return;
            player.GetComponent<FireFighterHeroController>().enabled = true;
            player.transform.Find("Camera").gameObject.GetComponent<CameraControler>().enabled = true;
            player.transform.Find("Camera").gameObject.GetComponent<CameraControler>().SetTarget(player.transform);
            player.transform.Find("Camera").gameObject.SetActive(true);
        }
}

相机控制器

public class CameraControler : MonoBehaviour
    {
        private Transform target;
        public Vector3 offset;

        public void SetTarget(Transform target)
        {
            this.target = target;
        }

        public void LateUpdate()
        {
            gameObject.transform.position = target.position + offset;
        }
    }
1个回答

3

更新 - 在您的评论后
您正在向所有玩家发送命令。

在发送命令之前,您应该检查接收命令的玩家是否是新玩家的所有者。

基本上你正在这样做。

=> 创建玩家
=> 分配相机

而你应该这样做。

=> 创建玩家
=> 检查此客户端是否为您自己 => 分配相机

为了实现这一点,您需要添加此检查:

if (photonView.IsMine) AssignCamera();

我看到你在管理器中发送命令。所以你有以下解决方法:
  • 在管理器中添加检测是否为玩家的方式
  • (更好的解决方案)将代码移动到玩家脚本中。

将代码添加到玩家脚本中

public class YourPlayer : Photon.MonoBehaviour
{
    public void Start()
    {
        //stop assigning controls if this is not the player related to this peer
        if(!photonView.IsMine) return;
        player.GetComponent<FireFighterHeroController>().enabled = true;
        player.GetComponent<CameraControler>().enabled = true;
        player.GetComponent<CameraControler>().SetTarget(player.transform);
    }
}

在管理器中添加检查

我不确定您代码的所有逻辑。一些代码应该适用于所有玩家,而另一些代码只适用于与对等玩家相关的玩家。

我认为您应该像这样更改Start方法:

public void Start()
{
    GameObject player = PhotonNetwork.Instantiate(this.playerPrefab.name, spawnPoint.position, Quaternion.identity);

    //stop assigning controls if this is not the player related to this peer
    if(!player.GetPhotonView().IsMine) return;
    player.GetComponent<FireFighterHeroController>().enabled = true;
    player.GetComponent<CameraControler>().enabled = true;
    player.GetComponent<CameraControler>().SetTarget(player.transform);
}

更多信息: 玩家网络-Photon PUN


嗨,是的,我已经阅读了文档并在提问之前尝试了这种方法。这不起作用,因为GameManager是场景上的一个单独对象,它没有PhotonView组件。PhotonView组件仅位于玩家的预制件中。我还尝试将此组件放入Game Manager中,但仍无法正常工作。无论如何,感谢您的帮助,我会继续尝试解决这个问题。 - scrinlock
你尝试过使用 player.GetPhotonView().IsMine 吗?你也可以将与相机控制器相关的3行代码移动到你的玩家Monobehaviour中,以达到同样的效果。我已经更新了答案。 - Jack Mariani
感谢您的帮助,您的建议促使我解决了这个问题,我已经更新了帖子。 - scrinlock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接