Unity 多人連線遊戲製作 |
本教學使用 Unity 製作多人連線射擊遊戲,玩家使用各種武器將對手擊倒獲得勝利。 匯入 PUN 2 - FREE 資源包,匯入 Toon Soldiers 資源包,或自行製作遊戲需要的角色。 開啟 PUN Wizard 對話框,從 Input AppId 輸入網頁取得的 AppId 後按下 Setup Project 按鈕,再按 Close 關閉對話框。
PUN Demo Hub 提供了多人連線遊戲的範例,建議可發佈遊戲後多開視窗測試看看 Photon 連線功能。 製作遊戲角色活動的場景地板,建立 "Floor" 標籤並指定給地面,稍後用於判定遊戲角色在地面與是否可跳躍。 開啟 [ Toon_Soldiers > ToonSoldiers_2 > prefabs ] 資料夾將 ToonSoldiers_infantry 拖曳到場景,並移到原點的位置。 建立一個動畫控制器並重新命名為 "Player Animator Controller" ,開啟後新增 Speed (Float) 與 Rotate (Float) 參數。 開啟 [ Toon_Soldiers > ToonSoldiers_2 > animation > Infantry ] 資料夾,將待機、行走、跳躍等動作加入動畫控制器。 ... 建立動作之間的過渡: 選取動畫過渡的箭頭,設定 Speed Grater 0.1 選取動畫過渡的箭頭,設定 Speed Less 0.1
選取玩家角色,將此角色重新命名為 “Player" ,附加 Rigidbody 剛體元件,勾選約束 Constraints Freeze Rotation XYZ 避免旋轉。 增加 Capsule Collider 膠囊碰撞器,調整中心位置與高度。 建立一個 C# 腳本命名為 "PlayerController" 並套用到 Player 玩家角色,程式碼如下: 目前只有基本的遊戲角色移動操作,按下 Play 測試遊戲確認目前沒問題。 選取 Player 玩家角色套用 Photon View 與 Photon Transform View 腳本元件。 建立 Resources 資料夾,將場景中的 Player 玩家角色拖曳到此資料夾,選擇 Original Prefab 製作預製物件。 建立 C# 腳本並命名為 "GameManager" 建立空物件並套用此腳本。 刪除場景中的 Player 玩家角色,儲存場景。 建立一個新場景,用於製作玩家登入畫面。 在此場景執行 [ GameObject > UI > Input Field] 建立文字欄位,並移到適當位置。 執行 [ GameObject > UI > Button ] 建立登入按鈕,移到適當位置,設定按鈕文字。 建立 C# 腳本並命名為 "NetworkManager" ,程式碼如下: 建立空物件命名為 "NetworkManager" 並將剛建立的腳本套用到此物件,透過 Inspector 指定 Input Field 與 Button 按鈕。 選取遊戲畫面的玩家名稱欄位, On Value Changed () + "NetworkManager" 再選取 "NetworkManager.OnNameFieldEdited". 注意!不是 NetworkManager.OnNameFieldEdited(String) 別選錯! 選取遊戲畫面的登入遊戲按鈕, On Click () + "NetworkManager" and select "NetworkManager.OnLoginButtonClicked". 儲存場景並將目前的遊戲場景加入 Scenes In Build 。 遊戲開發階段可增加自動登入功能,測試連線功能時,就不需要每次再切換回到登入場景。 儲存場景並發佈遊戲測試,玩家登入後會控制到場景上的所有的角色,必須判斷是否本地端的玩家以解決目前的問題。 開啟 PlayerController 腳本,修改程式碼: 透過以上修改即可解決 Photon 多人連線遊戲的遊戲角色控制問題。
增加玩家角色的跳躍動作目前只有行走動作,而且連線時動畫不同步,玩家只會看到自已角色的動作,畫面上的其他玩家只會飄移。 加入跳躍動作,開啟 Player Animator Controller 動畫控制器,加入 Infantry_jump_1_start 動作並新增動畫過渡。 選取「從待機到跳躍」的箭頭,取消 Has Exit Time 設定 Conditions 在 Jump 觸發時過渡到下個動作狀態。 選取「從走路到跳躍」的箭頭,取消 Has Exit Time 設定 Conditions 在 Jump 觸發時過渡到下個動作狀態。 ★ 開啟 PlayerController.cs 腳本,修改程式碼來加入跳躍動作: 接著解決動畫的同步問題,選取遊戲角色的預製物件,附加 Photon Animator View 腳本元件。 ★ 將 Synchronize Parameters 同步參數下,設定 Layer 0 = Continuous 進行動作狀態的持續同步。 實際上 Jump 跳躍動作也需要同步,但如果 Jump 使用 Trigger 觸發方式,將會出現警告訊息! When using triggers, make sure this component is last in the stack. If you still experience issues, implement triggers as a regular RPC or in custom IPunObservable component instead. (上圖)所以這邊的 Jump 維持 Disabled 修改程式碼: 注意! 參數增加減少時,建議回到 Photon Animator View 確認設定是否被重置。
增加玩家角色的後退動作將 Infantry_combat_idle 動作拖曳到 Player Animator Controller 動畫控制器。 新增從待機到後退動作的過渡箭頭(滑鼠右鍵 Make Transition)與後退到待機的回去箭頭。 選取「從待機到後退」的箭頭,取消 Has Exit Time 設定 Conditions 在 Speed Less -0.1 時過渡到後退的動作。 選取「從後退到待機」的箭頭,取消 Has Exit Time 設定 Conditions 在 Speed Greater -0.1 時過渡到待機的動作。
增加遊戲角色的跑步動作動畫控制器新增 Run 參數 修改 PlayerController 腳本,增加遊戲角色跑步的程式碼 選取從走路到跑步的箭頭,取消 Has Exit Time 設定 Conditions 在 Run = true 時過渡到下個動作狀態。 選取從跑步到走路的箭頭,取消 Has Exit Time 設定 Conditions 在 Run = false 時過渡到下個動作狀態。 選取從倒退到向後跑的箭頭,取消 Has Exit Time 設定 Conditions 在 Run = true 時過渡到下個動作狀態。 選取從向後跑到倒退的箭頭,取消 Has Exit Time 設定 Conditions 在 Run = false 時過渡到下個動作狀態。
增加遊戲角色的射擊功能開啟 Resources 資料夾,將 Player 玩家角色拖曳到場景再進行編輯。 選取玩家角色手上的武器,從 Hierarchy 視窗滑鼠右鍵執行 3D Object > Cutb 建立方塊物件。 此物件將是用於發射子彈的槍口,重新命名為 "Muzzle",稍後可關閉 Mesh Renderer 隱藏物件。 縮小方塊並移到槍口位置,刪除 Box Collider 方塊碰撞器。旋轉方向,讓 Z 軸藍色箭頭朝子彈前進的方塊。
製作子彈建立一個空物件並命名為 ”Bullet" 移到原點位置。 Bullet 套用 Rigidbody 剛體元件與 Capsule Collider 膠囊碰撞器。 Bullet 套用 Photon View 元件與 Photon Transform View 元件。 Bulet 滑鼠右鍵執行 3D Object > Capsule 建立一個膠囊子物件。 膠囊 X 軸旋轉 90 度,縮小到 0.1。 刪除膠囊子物件的碰撞器,再為上層的 Bullet 建立膠囊碰撞器。 新增一個 Bullet 標籤並套用到 Bullet 子彈物件。(現已有 Floor 標籤) Bullet 套用 Photon View, Photon Transform View腳本元件。★
建立一個 C# 腳本並命名為 "Bullet" ,使用 Rigidbody.AddRelativeForce 推動子彈,並於指定時間後刪除物件。 將 Bullet 腳本套用到 Bullet 子彈物件,設定推力 Thrust = 10 按下 Play 測試子彈功能,可套用 Trail Renderer 元件顯示飛行軌跡。 測試完成若無問題,將 Bullet 拖曳到 Resources 資料夾轉成預製物件,刪除場景中的 Bullet 子彈物件。
開啟 PlayerController 腳本元件,修改程式碼加入開槍射擊功能:
開啟 Player Animator Controller 動畫控制器,加入對應的射擊動作。 本例使用 [ Toon_Soldiers > ToonSoldiers_2 > animation > Infantry ] 資料夾的 infantry_combat_shoot 動作。 使用動畫層可以製作較複雜的動畫,無論是待機、前進、後退、跑步時,上半身都可做射擊動作。 按 + 新增動畫層並且命名為 Upper body 接著在 Project 視窗滑鼠右鍵執行 Create Avatar Mask ,命名為 Player Avatar Mask 。★ 選取後透過 Inspector 進行設定。展開 Humanoid 將下半身變成紅色,表示動畫在下半身將被遮蔽不受影響。 回到動畫編輯器切換到 Parameters 分頁按 + 新增 Shoot (Trigger) 參數。新增 Burst (Trigger) 參數。 ... 動畫編輯器切換到 Layers 分頁選擇 Upper body 設定權重 Weight = 1 完全控制,將 Mask 遮罩選擇剛建立的 Player Avatar Mask 遮罩。★ 設定 Bliding = Additive 混合動作。★ 在此動畫層執行 Create State > Empty 建立空狀態,再將攻擊動作拖曳進來。 建立狀態之間的過渡★,並透過 Inspector 設定過渡的條件。★★
修改攝影機製作 Unity 多人連線遊戲的攝影機與單機遊戲的差異,場景上可能同時有多個玩家角色,攝影機需要設定跟隨的目標。 使用 Standard Assets 的 MultipurposeCameraRig 攝影機,匯入 Standard Assets 資源包的 Cameras、CrossPlatformInput 資源。 ★ 開啟多人連線的主要遊戲場景,選取 預設的Main Camera 攝影機,停用或刪除此攝影機。 開啟 [ Standard Assets > Cameras > Prefabs ] 資料夾,將 MultipurposeCameraRig 拖曳到場景。 此攝影機可以自動追隨玩家移動,但需要修改為多人連線遊戲使用,開啟 GameManager.cs 腳本,修改程式碼: 按下 Play 測試遊戲,本地端的玩家角色動態生成後,攝影機將會跟隨本地端玩家,而不是其他玩家。 若出現 UnassignedReferenceException: The variable target of CameraController has not been assigned. 錯誤訊息,無需理會。
製作血條目前完成的進度是 Unity 多人連線的射擊遊戲,接著製作玩家的血條。 從 Hierarchy 視窗選取玩家角色,滑鼠右鍵執行 Create > UI > Canvas 。 建立一個 Text 文字用於顯示玩家名稱,調整到適當大小與位置,設定 Horizontal Overflow = Overflow 讓字數較多時也不換行。 建立一個 Slider 滑桿,將滑桿 Slider > Handle Slide Area 子物件停用或刪除。原本的 Slide 滑桿將會變成接近血條的外觀。 將滑桿 Slider > Fill Area 子物件的 Left 與 Right 設定為 0 。 將滑桿 Slider > Fill Area > Fill 子物件的 Width 設定為 0 。 建立 C# 腳本並命名為 "PlayerStats" 用於儲存連線玩家的狀態,此腳本的程式較多,請點擊圖片開啟連結。 將 PlayerStats 套用到玩家角色的預製物件。注意!不是場景中的遊戲角色。 將此預製物件下的玩家名稱、血條、最大 HP 數值、布偶預製物件設定到對應欄位。
修改 PlayerController 腳本,增加 PhotonView 與 playerStats 避免玩家角色倒地後仍被控制的問題。
修改 Bullet.cs 腳本,讓子彈擊中遊戲角色時執行扣血的功能。
修改 GameManager 腳本,讓玩家進入房間時進行資料同步更新。 修改 PlayerStats 腳本,增加被擊倒時的動作。廣播通知房間內的其他玩家進行資料同步更新。
|