获取其他玩家实例化的游戏对象 Unity Photon

Posted

技术标签:

【中文标题】获取其他玩家实例化的游戏对象 Unity Photon【英文标题】:Get other Players instantiated gameobjects Unity Photon 【发布时间】:2022-01-14 12:47:36 【问题描述】:

我正在尝试访问连接到同一房间的所有其他玩家的位置。我首先考虑获取已经实例化的游戏对象,但它们都具有相同的名称,因此无法正常工作。我不想使用地形生成器,但是当每个玩家生成地形时,它们都会相互混淆。所以我想也许只有第一个玩家必须为自己和所有其他玩家生成地形,但我现在不知道如何获得其他玩家的位置。因此我无法检查谁是第一个玩家。所以我的第二个问题是:是否有其他方法可以让一个人为所有人生成地形?

当我使用该名称访问我的播放器时,我只得到了我已经在玩的播放器,我尝试了一些我发送播放器坐标的方法,但只有当 photonView.isMine 不是 True 时才给出坐标。

到目前为止,这是我的代码,该脚本位于玩家预制件上,当玩家加入时会被实例化。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;



public class NetworkPlayer : Photon.MonoBehaviour

    private bool generatingTerrain;
    private Vector3 correctPlayerPos;
    private Quaternion correctPlayerRot;
    private GameObject LevelGenerator;
    private GameObject Player;
    private float pos;
    

    Rigidbody2D rb;
    void Start()
    
        LevelGenerator = GameObject.Find("LevelGenerator");
        generatingTerrain = LevelGenerator.transform.Find("Level Generator");
        Debug.Log(generatingTerrain);
        if (photonView.isMine)
        
            rb = GetComponent<Rigidbody2D>();
            rb.simulated = true;
            GetComponent<PlayerController>().enabled = true;
        
    

    void Update()
    
        //Debug.Log(generatingTerrain);
        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);
            Destroy(rb);
            Debug.Log("Transform Position on !isMine: " + transform.position.x.ToString());
            pos = transform.position.x;

        

        Player = GameObject.Find("Player_1(Clone)");
        if (photonView.isMine)
        
            Debug.Log("photonView.isMine: " + transform.position.x.ToString());
            Debug.Log("pos " + pos.ToString());
        


    
    void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
    
        if (stream.isWriting)
        
            // We own this player: send the others our data
            stream.SendNext(transform.position);
            stream.SendNext(transform.rotation);

        
        else
        
            // Network player, receive data
            this.correctPlayerPos = (Vector3)stream.ReceiveNext();
            this.correctPlayerRot = (Quaternion)stream.ReceiveNext();
        
    



也许我只是没看到什么,这是我第一次使用 unity 和 photon,所以我对这个话题真的很陌生。

如果你需要什么就写信给我,如果这里有什么东西丢失,我很抱歉 希望尽快得到帮助:)

【问题讨论】:

【参考方案1】:

就让其他玩家的位置正确,通过查看 photonView 是否不是我的。

我不完全确定您要对地形做什么。现在你正在尝试为游戏中的所有玩家生成地形,这将使游戏中的每个玩家对象都生成地形,这可能会导致混乱。

如果您想要程序生成地形,我建议您使用种子进行,然后在所有玩家之间共享种子。只有在 photonView.isMine 的情况下才应该生成地形。 如果你想改变地形,例如销毁或移动块,然后您需要通过网络同步它,最有可能使用事件或 RPC 调用。

【讨论】:

嘿,谢谢回复 我从来没有想过种子的事情,但对我来说似乎很聪明,所以我不必通过网络发送每个新的地形平台,只需要种子和每个玩家生成对于他自己来说,同样的地形,我的下一个问题是我如何分享种子?我看过如何通过网络共享变量,但我不确定它是如何工作的,以及我需要做什么 您不必通过网络发送,您可以在创建房间时将其添加到房间属性中。然后房间里的每个人都可以通过 PhotonNetwork.CurrentRoom.CustomProperties["seed"] 访问它。 这很好,因为这样即使原始主客户端断开连接,所有玩家都将获得种子... 嘿兄弟,我已经尝试实现这个,但我没有找到任何文档告诉我如何设置自定义属性,也许你可以帮助我...... 那里有很多信息,谷歌是你的朋友。但为了它:ExitGames.Client.Photon.Hashtable roomProperties = PhotonNetwork.CurrentRoom.CustomProperties; roomProperties["seed"] = "yourSeed"; PhotonNetwork.CurrentRoom.SetCustomProperties(roomProperties);【参考方案2】:

我找到了解决我的确切问题的方法:

GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
        foreach (GameObject p in players) 
            
            Debug.Log(p.transform.position);
            

这会列出每个获得玩家标签的游戏​​对象并将它们放入一个数组中,然后你可以访问它们中的每一个来检查它不是你自己的位置,你可以这样做:

if (p.position != gameobject.transform.position) 
    //Do here what you want to do with every Player who isnt you



我找到了解决方案here

【讨论】:

以上是关于获取其他玩家实例化的游戏对象 Unity Photon的主要内容,如果未能解决你的问题,请参考以下文章

Unity中获取游戏对象的几种方式

Unity 3d PhotonEngine 其他玩家如何获取masterclient生成的数据

unity游戏之太空射击

带有 Healthbar 的 Unity-Breakout 游戏

使用字符串 Unity 从游戏对象获取脚本

转载关于对方法实例化的相关感悟以及unity的50个技巧