使用Photon引擎進行unity網絡遊戲開發(四)——Photon引擎實現網絡遊戲邏輯

使用Photon引擎進行unity網絡遊戲開發(四)——Photon引擎實現網絡遊戲邏輯

網絡遊戲邏輯處理與MasterClient

網絡遊戲邏輯處理:

方法一:編寫Photon服務器與客戶端程序

客戶端傳遞數據之服務器,服務器完成邏輯判斷,並將結果返回給客戶端
enter description here

方法二:編寫客戶端程序

遊戲邏輯在客戶端處理,photon服務器只負責客戶端之間數據驗證和傳遞
enter description here

Master Client

  • 使用客戶端處理網絡遊戲邏輯時,必須保證遊戲房間內只有一個客戶端處理網絡遊戲邏輯,我們選擇某個客戶端來網絡處理遊戲邏輯
  • 這個客戶端根據其他客戶端發送的數據,處理網絡遊戲邏輯。之後,將處理結果發送給所有客戶端同步

PUN Master Client

在PUN的客戶端Client中,包含一個MasterClient,我們使用MasterClient來處理網絡遊戲邏輯

  • MasterCIient是PUN裏一個特殊的客戶端,每個遊戲房間Room有且僅有一個MasterClient
  • MasterCIient擁有比一般客戶端更高的權限,包括將其它客戶端踢出遊戲房間、管理網絡遊戲場景對象等
  • MasterClient離開房間後,GameServer會自動選擇ID最小的客戶端作爲MasterCIient
  • 使用PhotonNetwork.isMasterCIient判斷本地客戶端是否爲MasterCIient

玩家對象生成

Photon中生成玩家對象需要調用下面方法實例化。

  • ReSourcesPrefabName:需要實例化Prefab在resources文件下下名稱
  • Position:需要實例化對象的出生點
  • Quaternion:需要實例化對象的旋轉信息
  • Group:編組信息,方便區分各個對象,如區分出我方和敵方 PhotonNetwork.Instantiate("ReSourcesPrefabName",Position,Quaternion, Group)
    例如:
    //生成玩家對象
    void InstancePlayer()
    {
        playerCustomProperties = PhotonNetwork.player.CustomProperties;
        if (playerCustomProperties["Team"].ToString().Equals("Team1"))
        {
            localPlayer = PhotonNetwork.Instantiate("MyPlayer",
                TeamOneSpTrans[(int)playerCustomProperties["TeamNum"]].position, Quaternion.identity, 0);
        }
        //如果玩家屬於隊伍2,生成RobotPlayer對象
        else if (PhotonNetwork.player.CustomProperties["Team"].ToString().Equals("Team2"))
        {
            localPlayer = PhotonNetwork.Instantiate("MyPlayer",
                TeamTwoSpTrans[(int)playerCustomProperties["TeamNum"]].position, Quaternion.identity, 0);
        }

        localPlayer.name = PhotonNetwork.player.NickName;
    }

遊戲對象狀態同步

位置朝向信息同步

方法一:通過將Transfrom組件拖到PhotonView組件上的observed componentS屬性上。該方式儘管會傳輸對象的位置旋轉信息,但是由於通信間隔的存在,導致對象運動不連續

方法二:使用PhotonTransformView實現玩家位置與朝向的同步。

PhotonTransformView組件內置幾種插值算法,可以使用內置插值方法實現玩家的平滑“移動。

方法三:使用OnPhotonSerializeView(PhotonStream,PhotonMessageInfo)方法同步

使用該方法時需自行處理位置和旋轉的插值。

private 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  
        {  
            ...
            PlayerPosition = (Vector3)stream.ReceiveNext();  
            PlayerRotation = (Quaternion)stream.ReceiveNext();  
        }  
    }  

enter description here

enter description here

enter description here

enter description here

動畫信息同步

方法一:針對使用Animator組件的動畫,使用PhotonAnimatorView快速開發。

enter description here

方法二:使用OnPhotonSerializeView(PhotonStream,PhotonMessageInfo)方法同步。使用該方法將動畫參數的值傳遞,來實現動畫的同步,該方法對animation組件動畫適用。

Animation動畫:
如player有針對於其動畫的控制腳本,通過Update函數中的playerState來判斷動畫表現,這裏我們傳遞playerState來實現動畫同步

private void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)  
    {  
        if (stream.isWriting)  
        {  
            //We own this player: send the others our data  
            ...
           stream.SendNext(player.playerState);  
        }  
        else  
        {  
            ...
           player.playerState = (PlayAnimation)stream.ReceiveNext(); ;  
        }  
    }  

Animator動畫:
animator組件中通過各個參數來控制動畫的分支走向,這裏我們同步其參數來實現動畫同步

private void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)  
    {  
        if (stream.isWriting)  
        {  
            //We own this player: send the others our data  
            ...
           stream.SendNext(ani.GetFloat("RunSpeed"));  	
		   stream.SendNext(ani.GetBool("isJump"));  
        }  
        else  
        {  
            ...
           ani.SetFloat("RunSpeed",(string)stream.ReceiveNext());
		   ani.SetBool("isJump",(bool)stream.ReceiveNext());
        }  
    }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章