多人游戏相机的Unity3D奇怪行为

时间:2020-01-22 23:32:42

标签: unity3d camera multiplayer photon

我是新手,并为我的相机的异常行为而苦苦挣扎。 我正在使用Photon插件编写在线多人游戏。

奇怪的行为:

  • Player1登录

    ->都很好

  • Player2登录

    -> Player1的摄像机切换为Player2角色

    -> Player2的摄像机切换到Player1角色

  • Player3登录

    ->播放器1和播放器2的摄像机切换为播放器3字符

    -> 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 个答案:

答案 0 :(得分:1)

我的猜测是您在播放器上进行了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...");
    }

    ...
}