主題

【Unity x Photon】多人連線對戰遊戲,無痛線下轉線上的過程筆記

%%鼠 拒收病婿 | 2021-06-18 04:49:13 | 巴幣 2440 | 人氣 849

前言:
公司題目:1程式+1美術,三周內複製製作一款遊戲。
我們選Knight Club+,原本想直接做線上版,但公司希望能先做線下保險,有時間再改成線上。

我原本滿擔心的,沒做過線上移植,通常在做專案前都會直接設定好線下或線上,才去設計程式架構。但這次移植發現一些訣竅,滿成功、無痛的!


四人連線對打 影片: (因為有錄到公司人講話聲,所以禁音)

做法先一個個介紹。

1.角色動作切換
角色動畫有閒置、跑、起跳、跳躍中、落下中、落下踩地、二段跳、蹲下、閃避、重生、受傷、受傷擊飛、死亡、降落(開始動畫)、降落結束(開始動畫)、攻擊、上攻擊、下攻擊、防禦、停止....20組之多

如果用if else去判斷一定累死又難修改,好在我之前為了做這種遊戲所以做了個動作順序分配的工具,ActionController,最近優化了一下腳本,TimeOut不再用corotuine去算,而是在AddAction時再算就好。至於排序....應該要自己寫個Heap,不過那又是另外一個主題了~XD (舊版介紹文)

這次角色的動作表,(因為遊戲設計關係,攻擊的動作寫在身體部位)



2.線下當資料中繼站
若一開始設定要用線上作法,可能就會用Photon.CustomProperty去存資料,我也是開頭做到一半才被通知要先做線下的,慘了,寫到一半的東西難道要刪掉重寫?!  

所以我做一個類似Photon.CustomProperty的class去存資料:LocalPlayerProperty.cs。 Photon是用Hashtable,我選擇用dict,因為Dictionary<string, object> 可以達到一樣的效果且Dictionary查詢速度優於Hashtable。

第14行的Player _playerData = GetValue<Player>(CustomPropertyCode.PLAYER);  
因為有4個玩家,所以我會在創建玩家時給予player index與上傳Photon的Player設定,例:
(CustomPropertyCode是我用來統整Key值的腳本")

這個還是本機端的資訊,若要同步更新的話需再搭配UpdateOnlineProperty.cs
LocalRoomManager我寫得滿亂的,主要就是用來記錄本機玩家的資訊:
public List<LocalPlayerProperty> players = new List<LocalPlayerProperty>();

(players 數量會等於玩家數量(本機版跟線上版)),所以35行以下是我得到其他玩家更新的資訊時,同步更新本端的資訊,等於有4個玩家就會有4分玩家資訊的拷貝。



3.動作同步
假設現在有ABC三個玩家:
A電腦的A按下WASD移動,其PlayerControl會給ActionController指派 Move()的方法,其包含1.移動、2.播放移動動畫 兩個事情。
移動是透過PhotonView同步,所以我們可以只傳送PlayAnimation()方法告訴BC電腦裡面的A物件去播放移動動畫。 關於Photon的基本知識可以先看之前的筆記1筆記2

夠過RPC呼叫PlayAnimation可以自動掛載上move的方法。 例:
walk.action.AddListener(delegate { DoRpcOnAllOtherPlayers("Walk_animation"); });

DoRpcOnAllOtherPlayers只是不要重複呼叫到自己端的物件。

Walk_animation只是播放動畫(因為遊戲設計,所以需拆分成頭跟身體)。
   [PunRPC]
    public void Walk_animation()
    {
        head.PlayAnimation("Walk");
        body.PlayAnimation("Walk");
    }

更多可以看我的PlayerControl腳本 236行左右。



4.互動動作同步
上面講的都只是單個物件的互動,但若是兩個物件的互動關係呢?
假設A攻擊B,B的HP-100。


透過上面的方法讓AB都呼叫播放動畫,但此時只有同步動畫資訊而已。在A的電腦B的血量已經-100了,但B、C電腦的B物件血量仍是滿的。
但若透過最上面講述的方法,讓B的血量寫進local data,並在寫入時偵測是否是線上版,則更新至線上資料庫,達到同步資訊。   (當然,本專案實際寫法不是這樣直接,但概念差不多)

筆記1不同之處如筆記2最後所述,筆記1只sync死亡事件,並沒有同步HP資訊。

7/7更新:
若A打B,但因延遲問題,在B的電腦其實B已經躲掉了,但照著上面的邏輯,A打B更新的血量會更新到B電腦上的自己,這會讓B感到生氣,明明躲掉了卻還是受傷,所以正確做法是B電腦的B自己被打,血量才會更新給大家。



5.好處
大部分的東西可以只做一個,例如角色操作腳本與場景:
(角色的選擇畫面其實可以合併成一個,但當時我還沒想到這方法XD)


後記:
整個專案總共經歷3種同步的作法,亂亂的QQ....
打到一半還才去研究打程式的規範,後期有盡量維持統一,不過前期還是一團糟。

不過每次修改都能想到更好的方法,覺得很值得

此趟旅行的紀念品大概就是上述github的檔案

度了,遊戲是線上版,所以有興趣是可以大家下載來玩玩啦~ 不過怕之後報告出意外,載點還是之後再提供吧XD。



雜紀:
最近家裡好多事情....  家人化療、喪事、房間鬧鬼、最近還跟最親近的人吵架。  最近食慾大減,常忘了打卡午休去吃飯。

送禮物贊助創作者 !
0
留言

創作回應

樂小呈
每次修改都能想到更好的方法[e12]
2021-06-18 10:41:28
樂小呈
拍拍,辛苦了
2021-06-18 10:41:50
%%鼠 拒收病婿
感謝[e5]
2021-06-18 15:34:14
迷途巴哥
好讚喔[e17]
2021-06-18 13:57:36
%%鼠 拒收病婿
突發奇想[e16]
2021-06-18 15:34:39
KK
辛苦了!自己的身體也要多保重
2021-06-18 23:24:20
%%鼠 拒收病婿
感謝[e35]
2021-06-20 17:51:47

相關創作

更多創作