Photon Unity Networking基礎(chǔ)教程 7 修改Player的聯(lián)網(wǎng)版本

Photon Unity Networking基礎(chǔ)教程 7 修改Player的聯(lián)網(wǎng)版本

本節(jié)將指導(dǎo)您修改Player Prefab。我們首先創(chuàng)建一個(gè)可以工作的player,但現(xiàn)在我們將修改它,以便它在PUN環(huán)境中使用時(shí)能正常工作牡属。修改很少的代碼,但概念是至關(guān)重要的扼睬。所以這一節(jié)非常重要。

主要內(nèi)容

  • PhotonView 組件
  • Transform 同步
  • Animator 同步
  • 用戶輸入管理
  • Camera 控制
  • Beams 開火控制
  • Health 同步

PhotonView 組件

首先悴势,我們需要在Prefab上添加一個(gè)PhotonView組件窗宇。PhotonView將每個(gè)計(jì)算機(jī)上的各種實(shí)例連接在一起,并定義要觀察的組件以及如何觀察這些組件特纤。

  • 添加PhotonView組件到My Robot Kyle
  • 將Observe Option設(shè)置為Unreliable On Change
  • 注意军俊,PhotonView警告你,要起作用的話你需要觀察一些東西

讓我們?cè)O(shè)置我們要觀察的對(duì)象捧存,然后我們將回到這個(gè)PhotonView組件粪躬,并完成它的設(shè)置。

Transform 同步

我們想要同步的明顯特征是角色的位置和旋轉(zhuǎn)昔穴,使得當(dāng)Player移動(dòng)時(shí)镰官,其他計(jì)算機(jī)上的Player也以類似的方式移動(dòng)和旋轉(zhuǎn)。

你可以直接觀察自己腳本中的Transform組件吗货,但是由于網(wǎng)絡(luò)延遲和數(shù)據(jù)同步的有效性泳唠,你會(huì)遇到很多麻煩。幸運(yùn)的是宙搬,為了使這個(gè)常見的任務(wù)更容易笨腥,我們將使用[Photon Transform View]組件,作為變換組件和PhotonView之間的中間人(middleMan)勇垛〔蹦福基本上,這個(gè)組件已經(jīng)為你做了所有的工作闲孤。

  1. 給'My Robot Kyle'Prefab添加PhotonTransformView
  2. 拖拽PhotonTransformView的標(biāo)題欄到PhotonView組件的第一個(gè)Observable組件上
ObservePhotonTransformView.gif
  1. 在PhotonTransformView組件上勾選Synchronize Position
  2. 在Synchronize Position里面谆级,Interpolation Option選擇“Lerp”
  3. 把Lerp Speed設(shè)置為10(數(shù)值越大插值越快)
  4. 勾選SynchronizeRotation
PrefabPhotonTransformView.png
提示:注意右邊的藍(lán)色書本幫助鏈接,點(diǎn)擊它能獲取信息崭放,學(xué)習(xí)不同的設(shè)置和效果哨苛。
PrefabPhotonTransformViewHelp.png

Animator 同步

PhotonAnimatorView也使得網(wǎng)絡(luò)設(shè)置變得輕而易舉,將為您節(jié)省大量的時(shí)間和麻煩币砂。它允許您定義哪些層權(quán)重和要同步的參數(shù)建峭。層權(quán)重只有在游戲過程中改變了才需要同步,并且可以不同步它們决摧。參數(shù)也是如此亿蒸。有時(shí)可以從其他因素導(dǎo)出動(dòng)畫值凑兰。速度值是一個(gè)很好的例子,你不一定需要讓這個(gè)值完全同步边锁,但你可以使用同步的位置更新來估計(jì)它的值姑食。如果可能,嘗試同步盡可能少的參數(shù)茅坛。

  1. 給My Robot Kyle Prefab添加一個(gè)PhotonAnimatorView
  2. 拖拽PhotonAnimatorView的標(biāo)題欄到PhotonView組件的Observable組件上
  3. 同步參數(shù)中設(shè)置Speed為Discrete
  4. 設(shè)置Direction為Discrete
  5. 設(shè)置Jump為Discrete
  6. 設(shè)置Hi為Disabled
ObservePhotonAnimatorView.gif

每個(gè)值都可以是disabled音半,或者以離散(discretely)或連續(xù)(continuously)的方式同步(synchronized)。在我們的例子中贡蓖,由于我們不使用Hi參數(shù)曹鸠,我們將禁用它,從而節(jié)省帶寬斥铺。

離散同步(Discrete synchronization)意味著值每秒發(fā)送10次(在OnPhotonSerializeView中)彻桃。 接收客戶端將值傳遞到他們的本地Animator。

連續(xù)同步(Continuous synchronization)意味著PhotonAnimatorView每幀都要運(yùn)行晾蜘。當(dāng)調(diào)用OnPhotonSerializeView(每秒10次)時(shí)邻眷,自上次調(diào)用以來記錄的值一起發(fā)送。接收客戶端然后按順序應(yīng)用值以保持平滑過渡剔交。雖然此模式更平滑肆饶,但它為了實(shí)現(xiàn)此效果發(fā)送了更多數(shù)據(jù)。

用戶輸入管理

用戶控制網(wǎng)絡(luò)的一個(gè)關(guān)鍵方面是省容,相同的Prefab將為所有玩家實(shí)例化抖拴,但是其中只有一個(gè)是實(shí)際在計(jì)算機(jī)前的用戶控制的,所有其他實(shí)例代表的是在其他計(jì)算機(jī)上的其他用戶腥椒。因此阿宅,這一點(diǎn)的第一個(gè)障礙是輸入管理。我們?nèi)绾文軌蛟谝粋€(gè)實(shí)例上而不是在其他實(shí)例上啟用輸入笼蛛,以及如何知道哪個(gè)是正確的洒放?這就需要isMine的概念。

讓我們編輯我們之前創(chuàng)建的PlayerAnimatorManager腳本滨砍。在目前的形式中往湿,這個(gè)腳本不知道這個(gè)區(qū)別,讓我們實(shí)現(xiàn)它惋戏。

  1. 打開腳本PlayerAnimatorManager

  2. 把PlayerAnimatorManager的基類改為Photon.MonoBehaviour领追,這個(gè)類很方便的暴露photonView的組件

  3. 在Update函數(shù)的開頭加入下面代碼

     if( photonView.isMine == false && PhotonNetwork.connected == true )
     {
         return;
     }
    
  4. 保存腳本

Ok,如果實(shí)例由“客戶端”應(yīng)用程序控制响逢,PhotonView.isMine將為true绒窑,意味著此實(shí)例表示在此應(yīng)用程序中在此計(jì)算機(jī)上正在play的玩家。因此舔亭,如果它是假的些膨,我們不想做任何事情蟀俊,只依靠PhotonView組件來同步我們之前設(shè)置的變換和動(dòng)畫組件。

但是订雾,為什么在我們的if語句中強(qiáng)制執(zhí)行PhotonNetwork.connected == true肢预?因?yàn)樵陂_發(fā)期間,我們可能想要測試這個(gè)prefab洼哎,而不連接烫映。在虛擬場景中,例如噩峦,只是創(chuàng)建和驗(yàn)證與網(wǎng)絡(luò)功能無關(guān)的代碼窑邦。因此,使用這個(gè)附加表達(dá)式壕探,如果我們沒有連接,我們將允許使用輸入郊丛。這是一個(gè)非常簡單的伎倆李请,并將大大改善您的開發(fā)過程中的工作流。

Camera 控制

它和輸入一樣厉熟,Player只有一個(gè)游戲視圖导盅,所以我們需要CameraWork腳本只跟隨本地Player,而不是其他Player揍瑟。這就是為什么CameraWork腳本有這個(gè)能力來定義什么時(shí)候跟隨白翻。

讓我們修改PlayerManager腳本來控制CameraWork組件。

  1. 打開PlayerManager腳本

  2. 在Awake()和Update()函數(shù)之間插入下面的代碼

     /// <summary>
     /// MonoBehaviour method called on GameObject by Unity during initialization phase.
     /// </summary>
     void Start()
     {
         CameraWork _cameraWork = this.gameObject.GetComponent<CameraWork>(); 
         if (_cameraWork!=null )
         {
             if ( photonView.isMine)
             {
                 _cameraWork.OnStartFollowing();
             }
         }else{
             Debug.LogError("<Color=Red><a>Missing</a></Color> CameraWork Component on playerPrefab.",this);
         }
     }
    
  3. 保存腳本

首先绢片,它獲取CameraWork組件滤馍,我們期望這樣,所以如果我們沒有找到它底循,就記錄一個(gè)錯(cuò)誤巢株。然后,如果photonView.isMine為true熙涤,這意味著我們需要跟隨這個(gè)實(shí)例阁苞,因此我們調(diào)用_cameraWork.OnStartFollowing(),它有效地使相機(jī)跟隨場景中的那個(gè)實(shí)例祠挫。

所有其他Player實(shí)例的photonView.isMine將設(shè)置為false那槽,因此它們各自的_cameraWork將不會(huì)做任何事情。

下面的一個(gè)改變可以使這點(diǎn)生效

  1. 在Robot animator prefab上等舔,CameraWork組件中禁用Follow on Start屬性
CameraWorkFollowOnStartOff.png

PlayerManager腳本將會(huì)像上面描述的那樣調(diào)用_cameraWork.OnStartFollowing()骚灸,現(xiàn)在這有效的處理了跟隨Player的邏輯。

Beams 開火控制

開火也同樣遵循上面的輸入原則软瞎,它只在photonView.isMine是true的情況下工作逢唤。

  1. 打開PlayerManager腳本

  2. 用一個(gè)if語句包住輸入處理

     if (photonView.isMine) {
         ProcessInputs ();
     }
    
  3. 保存腳本

然而拉讯,當(dāng)測試這個(gè)的時(shí)候,我們只看到本地Player開火鳖藕。我們需要看看其他實(shí)例何時(shí)開火魔慷!我們需要一種用于在網(wǎng)絡(luò)上同步開火的機(jī)制。為此著恩,我們將手動(dòng)同步IsFiring布爾值院尔,直到現(xiàn)在,我們離開了PhotonTransformView和PhotonAnimatorView來為我們進(jìn)行變量的所有內(nèi)部同步喉誊,我們只需要調(diào)整通過Unity Inspector方便地暴露給我們的參數(shù)邀摆,但在這里我們需要的是,針對(duì)你的具體游戲伍茄,所以我們需要手動(dòng)這樣做栋盹。

  1. 打開PlayerManager腳本
  2. 實(shí)現(xiàn)IPunObservable接口
PlayerManagerIpunObsverableImplementation.gif
  1. 在IPunObservable.OnPhotonSerializeView函數(shù)中添加下面代碼

     if (stream.isWriting)
     {
         // We own this player: send the others our data
         stream.SendNext(IsFiring);
     }else{
         // Network player, receive data
         this.IsFiring = (bool)stream.ReceiveNext();
     }
    
  2. 保存腳本

  3. 回到Unity編輯器,在assets中選擇Robot Animator prefab敷矫,在PhotonView組件中添加一條監(jiān)視記錄例获,然后把PlayerManager組件拖拽到上面

PrefabObservePlayerManager.png

沒有上一步的話,IPunObservable.OnPhotonSerializeView永遠(yuǎn)不會(huì)調(diào)用曹仗,因?yàn)樗鼪]有被PhotonView監(jiān)視榨汤。

在這個(gè)IPunObservable.OnPhotonSerializeView方法中,我們傳遞了一個(gè)變量stream怎茫,這是將通過網(wǎng)絡(luò)發(fā)送的收壕,并且這個(gè)調(diào)用是我們讀寫數(shù)據(jù)的機(jī)會(huì)。當(dāng)我們是本地Player的時(shí)候(PhotonView.isMine == true)才能寫入數(shù)據(jù)轨蛤,否則是讀數(shù)據(jù)蜜宪。

由于stream類自己知道該怎么處理數(shù)據(jù),所以我們只需要簡單的利用stream.isWriting祥山,就可以知道當(dāng)前實(shí)例情況下要做什么端壳。

如果我們期望寫入數(shù)據(jù),我們使用stream.SendNext()附加到數(shù)據(jù)流的IsFiring值枪蘑,這是一個(gè)非常方便的方法损谦,隱藏了數(shù)據(jù)序列化的所有辛苦工作。如果我們希望讀數(shù)據(jù)岳颇,那就使用stream.ReceiveNext()照捡。

Health 同步

好的,為了完成更新Player的功能话侧,我們將同步Health值栗精,以便Player的每個(gè)實(shí)例都有正確的Health值。這與我們剛剛介紹的IsFiring值使用完全相同的原則。

  1. 打開腳本PlayerManager

  2. 在IPunObservable.OnPhotonSerializeView中悲立,SendNext和ReceiveNext處理IsFiring變量之后鹿寨,同樣的處理一下Health

     if (stream.isWriting)
     {
         // We own this player: send the others our data
         stream.SendNext(IsFiring);
         stream.SendNext(Health);
     }else{
         // Network player, receive data
         this.IsFiring = (bool)stream.ReceiveNext();
         this.Health = (float)stream.ReceiveNext();
     }
    
  3. 保存PlayerManager

這樣就完成了同步Health變量。

原文

http://doc.photonengine.com/en-us/pun/current/tutorials/pun-basics-tutorial/player-networking

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末薪夕,一起剝皮案震驚了整個(gè)濱河市脚草,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌原献,老刑警劉巖馏慨,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異姑隅,居然都是意外死亡写隶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門讲仰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慕趴,“玉大人,你說我怎么就攤上這事鄙陡≈确。” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵柔吼,是天一觀的道長。 經(jīng)常有香客問我丙唧,道長愈魏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任想际,我火速辦了婚禮培漏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘胡本。我一直安慰自己牌柄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布侧甫。 她就那樣靜靜地躺著珊佣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪披粟。 梳的紋絲不亂的頭發(fā)上咒锻,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音守屉,去河邊找鬼惑艇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的滨巴。 我是一名探鬼主播思灌,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼恭取!你這毒婦竟也來了泰偿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤秽荤,失蹤者是張志新(化名)和其女友劉穎甜奄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窃款,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡课兄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晨继。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烟阐。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖紊扬,靈堂內(nèi)的尸體忽然破棺而出蜒茄,到底是詐尸還是另有隱情,我是刑警寧澤餐屎,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布檀葛,位于F島的核電站,受9級(jí)特大地震影響腹缩,放射性物質(zhì)發(fā)生泄漏屿聋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一藏鹊、第九天 我趴在偏房一處隱蔽的房頂上張望润讥。 院中可真熱鬧,春花似錦盘寡、人聲如沸楚殿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脆粥。三九已至,卻和暖如春影涉,著一層夾襖步出監(jiān)牢的瞬間冠绢,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國打工常潮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弟胀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像孵户,于是被迫代替她去往敵國和親萧朝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容