這篇分為2個部分
1.網路架構基本概念
2.讓玩家登入吧
前言:
unity在5.x以後使用了的新的網路連線方法,簡稱UNet
為了解說方便,製作一個遊戲名叫 搶奪20 / Rob20 的連線小遊戲
規則:
兩個人輪流喊1~2個數字,先搶到20的人勝利
網路架構基本概念
1.UNet 是個以 Server 為主導的系統
2.每個物件都需要有Network Identity
白話文:
譬如說在遊戲的角色做了蹲下這個動作,就必須要告知Server,在由Server同步到其他玩家的遊戲畫面上。
所以一個玩家操控的角色,至少會有3個"分身",一個在自己電腦上,一個在別人電腦上,一個在Server上。
所以不像單機遊戲的寫法,C#的方法(method)又分為在Server執行、在Client執行兩種。
以場景(Scene)來說,也要注意物件會根據 Server或是Client而有不同。
Network Identity又是甚麼呢,比較像是一個在網路連線功能上的一個身分證,場景中的物件要有這個元件才能正常運作~
Network Identity 有Server only與Local Player Authorit兩個選項,這是一種"權限"的概念,就是這個物件歸誰管的意思啦。
比較簡單的分法:
玩家的角色會把Local Player Authorit打勾,邏輯處理的物件會把Server only打勾
Server only打勾的話,那這個物件就只會在Server端才能看到,把Local Player Authorit打勾或是都不勾的話 Server 端與 Client 端都會有
只在Server上出現的物件,拿來做邏輯的判斷,還有處理各個玩家發送過來的訊息。
有了一些基本概念後就接著製作下去吧~
讓玩家登入吧
這個遊戲要讓兩個玩家能連線,還要在他們的畫面上顯示自己的角色圖示
這邊用兩個不同的圖案來當作角色
伺服器端
Server這邊要能夠知道玩家已連線,並告知玩家是玩家1 或是玩家2
1.首先新增一個物件,命名為GM
2.新增Network Identity,必把Server only打勾
3.新增Script命名為GM
在GM.cs先把原本的都砍掉,然後輸入這幾行
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class GM : MonoBehaviour
{
public List<Player> allPlayer = new List<Player>();
public void Login(Player player)
{
allPlayer.Add(player);
player.RpcSetPlayer(allPlayer.Count);
}
}
解說:
Login()是要讓玩家登入
allPlayer會記錄現在登入的玩家
第一次輸入時會有錯誤的情況,不過沒關係,馬上來製作Client端的物件
如果unity錯誤到無法繼續編輯,可以先把GM的勾勾掉
玩家端 玩家的部分用canvas做一個顯示角色的地方,每個玩家顯示的角色圖示要不一樣
1.新增一個Canvas,命名為cvsClient
2.新增Network Identity,把Local Player Authorit打勾
1.新增兩個UI > Image在 cvsClient 底下
2.調整位置
3.把 player1.png 與 player2.png 拖到對應的位置上
4.把物件本身的勾勾掉,讓圖片物件失效
1.把cvsClient拖至Project頁籤的區塊,讓它變成Prefab
1.把變成 Prefab 的 cvsClient 拖至 NetworkMsg 的 Player Prefab上,透過這個動作註冊物件,告訴 unity 這個物件代表玩家,並且在玩家連線成功時自動產生在場景上
2.刪除場景中的cvsClient
3.繼續在Prefab上的cvsClient操作
新增一個Script命名為Player,把原本的全部砍掉,然後輸入這幾行
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Player : NetworkBehaviour
{
public Image ImgPlayer1;
public Image ImgPlayer2;
GM gm;
void Start()
{
if (isServer)
{
gm = GameObject.Find("GM").GetComponent<GM>();
gm.Login(this);
}
}
[ClientRpc]
public void RpcSetPlayer(int id)
{
if (isLocalPlayer)
{
switch (id)
{
case 1:
ImgPlayer1.gameObject.SetActive(true);
break;
case 2:
ImgPlayer2.gameObject.SetActive(true);
break;
}
}
}
}
這裡會有點難懂~~請加油~
首先呢出現了第一個新的東西叫 NetworkBehaviour 而不是 MonoBehaviour,繼承它可以讓我們用一些額外的功能。
還記得之前說過的玩家角色至少會有3個"分身"嗎,當玩家連線成功時,Server會在這3個地方創建出cvsClient。
當cvsClient被創建時,第一步會先執行Start區塊內的程式,但是GM只有在Server端才有阿,所以要用isServer去判斷。
isServer 就是 NetworkBehaviour 提供的變數,它會自動判斷執行它的環境是否在Server上。
只有在 Server 端的cvsClient去進行 Login(),GM.cs 中的 Login()又呼叫了 Player.cs 中的 RpcSetPlayer(),並把玩家順位傳遞進去。
[ClientRpc]這個標籤很特別,它的功能就告訴 unity 這個方法是在Server 端被呼叫, Client 端去執行。
然後 Client 端的 Player.cs 就依據接收到的參數來顯示相對應的玩家圖示。
流程是這樣:
1.Server上的Player.cs呼叫Server上的GM.cs的Login();
2.Server上的GM.cs呼叫Server上的Player.cs 的 RpcSetPlayer()
3.Server上的Player.cs 的 RpcSetPlayer()被呼叫後實際是執行 Client上的Player.cs 的 RpcSetPlayer()
細部解說:
using UnityEngine.Networking; |
寫網路功能必備 |
NetworkBehaviour |
繼承MonoBehaviour,提供了 isServer、isClient等參數 |
[ClientRpc] |
這個標籤所標示的方法只會在Client端執行 |
編譯成exe檔執行看看
開兩個遊戲視窗,一個選Host一個選Client
可以看到Host玩家顯示的是三角形,另一個是五角形
那就表示成功囉~
這篇就到這篇結束囉~
下一篇會講按鈕功能製作和數字面板同步更新的方法
感謝各位的觀看!!