使用Photon引擎進行unity網絡遊戲開發(四)——Photon引擎實現網絡遊戲邏輯
網絡遊戲邏輯處理與MasterClient
網絡遊戲邏輯處理:
方法一:編寫Photon服務器與客戶端程序
客戶端傳遞數據之服務器,服務器完成邏輯判斷,並將結果返回給客戶端
方法二:編寫客戶端程序
遊戲邏輯在客戶端處理,photon服務器只負責客戶端之間數據驗證和傳遞
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();
}
}
動畫信息同步
方法一:針對使用Animator組件的動畫,使用PhotonAnimatorView快速開發。
方法二:使用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());
}
}