1.整體遊戲流程控制
2.各別玩家的流程控制
前言:
unity在5.x以後使用了的新的網路連線方法,簡稱UNet
為了解說方便,製作一個遊戲名叫 搶奪20 / Rob20 的連線小遊戲
規則:
兩個人輪流喊1~2個數字,先搶到20的人勝利
看此篇前建議先看前面的篇章喔
連線小遊戲製作part1
連線小遊戲製作part2
連線小遊戲製作part3
這篇是程式碼時間~dadatada~
我們使用enum來做流程個控制,enum就是列舉的意思,把遊戲的流程一一列舉出來,依據需要去切換~
首先呢先在GM.cs裡增加這幾行
public enum Round
{
non,
player1,
player2
}
public enum Process
{
start,
waitLogin,
decidePlayer,
p1Action,
p2Action,
checkWin,
end,
}
Round是回合,表示現在是哪一個玩家的回合
Process是遊戲流程
解說:
start | 遊戲初始化 |
waitLogin | 等待玩家登入 |
decidePlayer | 決定現在是哪個玩家進行動作 |
p1Action | 玩家1的回合 |
p2Action | 玩家2的回合 |
checkWin | 檢查數字是否達到勝利條件20 |
end | 遊戲結束 |
就玩家的角度來說,流程就比較點單,主要是你的回合或他的回合這兩個部分
在Player.cs 新增這幾行
public enum Process
{
start,
action,
wait,
end
}
這裡的Process是玩家的流程:
start | 遊戲初始化 |
action | 自己的回合 |
wait | 對方的回合 |
end | 遊戲結束 |
列舉了之後呢,我們希望遊戲達到想要的流程:
1.GM.cs可以控制每個玩家的流程狀態
2.一開始會先等待兩個玩家登入,Player.cs的流程狀態就是start
3.直到有兩個玩家登入時,GM.cs要讓玩家1先開始回合
4.玩家1的回合時玩家1的流程狀態就是action ,玩家2就是wait,反過來也一樣
5.兩個玩家輪流進行遊戲直到達勝利條件,GM.cs就會讓流程狀態變為end,結束遊戲
所以們要在Player.cs裡增加這幾行,讓Server有辦法控制Client的流程狀態
[SyncVar]
public Process process = Process.start;
[SyncVar]
public string SysMsg;
public void SetProcess(Process process)
{
this.process = process;
}
[SyncVar]會同步Server端的Player.cs的參數到Client端
SysMsg是用來接收Server傳送過來的訊息用的
為了要讓SysMsg的訊息可以顯示在玩家的畫面上,要在Player.cs的Start()與Update()裡增加幾行~
void Start()
{
if (isServer)
{
gm = GameObject.Find("GM").GetComponent<GM>();
gm.Login(this);
}
if (isLocalPlayer)
{
txtSysMsg = GameObject.Find("txtSysMsg").GetComponent<Text>();★
txtMunber = GameObject.Find("txtMunber").GetComponent<Text>();
btnAddOne = GameObject.Find("btn1").GetComponent<Button>();
btnAddTwo = GameObject.Find("btn2").GetComponent<Button>();
btnAddOne.onClick.AddListener(() => CmdAddMunbers(1));
btnAddTwo.onClick.AddListener(() => CmdAddMunbers(2));
}
}
void Update()
{
if (isServer)
Munber = gm.Mumber;
if (isLocalPlayer)
{
txtSysMsg.text = SysMsg;★
txtMunber.text = Munber.ToString();
}
}
有☆表示新增的,其他都依樣~
跟所有介面一樣,要在Start()先抓到實體,在用Update跟新文字的內容
接著換GM.cs,先新增這幾行,這裡我們用Update()來做流程的處理
public Round round = Round.non;
public Process process = Process.start;
int roundCount = 0;
void Start()
{
process = Process.waitLogin;
}
void Update()
{
switch (process)
{
case Process.waitLogin:
foreach (Player pl in allPlayer)
pl.SysMsg = "等待玩家連線...";
break;
case Process.decidePlayer:
roundCount++;
if (roundCount % 2 == 1)
{
round = Round.player1;
process = Process.p1Action;
}
else
{
round = Round.player2;
process = Process.p2Action;
}
break;
case Process.p1Action:
allPlayer[0].SysMsg = "輪到你了!";
allPlayer[0].SetProcess(Player.Process.action);
allPlayer[1].SysMsg = "等待對方...";
allPlayer[1].SetProcess(Player.Process.wait);
break;
case Process.p2Action:
allPlayer[1].SysMsg = "輪到你了!";
allPlayer[1].SetProcess(Player.Process.action);
allPlayer[0].SysMsg = "等待對方...";
allPlayer[0].SetProcess(Player.Process.wait);
break;
case Process.checkWin:
switch (round)
{
case Round.player1:
allPlayer[0].SysMsg = "Winner";
allPlayer[1].SysMsg = "Loser";
break;
case Round.player2:
allPlayer[1].SysMsg = "Winner";
allPlayer[0].SysMsg = "Loser";
break;
}
allPlayer[0].SetProcess(Player.Process.end);
allPlayer[1].SetProcess(Player.Process.end);
process = Process.end;
break;
}
}
這裡可以發現每個流程都有相對應的case區塊去做處理
首先在遊戲啟動時Start()會先把流程狀態切換成waitLogin,用foreach的方式來告訴已經登入的玩家,目前正等待第2個玩家
那流程狀態如何從 waitLogin 切換到正式開始遊戲呢
要在GM.cs裡的 AddPlayer()增加判斷
public void AddPlayer(ClientLogic cl)
{
if (process == Process.waitPlayer)
{
Players.Add(cl);
if (Players.Count == 2)
process = Process.decidePlayer;
}
}
這樣只要登入玩家有兩個的時候,流程狀態就會變成decidePlayer,就是遊戲正式開始囉
接著在decidePlayer中,主要的任務是決定現在是誰的回合
1.roundCount從0開始每回合+1,用%2來取除以2的餘數
2.如果餘數是1就是玩家1的回合,餘數是0就是玩家2的回合
3.決定是誰的回合後,流程狀態就會切換p1Action或是p2Action
在p1Action主要任務是讓玩家1的Player.cs的流程狀態切換為Action,玩家2則是wait
並發"送輪到你了~"或是"等待對方的訊息",反過來也是一樣
而且玩家只有在自己的回合才能喊數字,為了達成這樣的效果,我們要在Player.cs的CmdAddMunbers()裡增加一行判斷
[Command]
public void CmdAddMunbers(int addMun)
{
if (process == Process.action)★
gm.AddMunber(addMun);
}
玩家的流程狀態要在action時按下按鈕才能喊數字,其他的流程狀態喊是沒有用的喔。
玩家喊完數字(+1或+2)的時候,就要換另外一位玩家的回合,流程狀態也就接著改變,所以要在GM.cs裡的AddMunber()裡增加一行
public void AddMunber(int addMun)
{
Mumber += addMun;
process = Process.decidePlayer;★
}
這樣的話每當玩家喊了數字以後在GM.cs這裡的流程狀態就會變成decidePlayer,經過roundCount的計算與判斷後,就換下一個玩家的回合。
直到數字是20! 那喊到20的那位玩家就贏了,那繼續在AddMunber()裡增加幾行
public void AddMunber(int addMun)
{
Mumber += addMun;
if (Mumber >= 20)★
process = Process.checkWin;★
else★
process = Process.decidePlayer;
}
如果Munber大於或等於20,那流程狀態就會切換成checkWin,這時就會判斷目前是誰的回合,然後給贏家發送Winner的訊息,輸家則是發送Loser的訊息
寫到這邊,遊戲已經完成90%囉~~恭喜~
不過還是先編譯成exe來測試看看吧
這篇先到這邊結束了~
下一篇就來稍微美化一下遊戲,還有講解Match Maker的用法
先恭喜看到這邊的你~ 遊戲已經接近完成囉!!
error CS0246: The type or namespace name `ClientLogic' could not be found. Are you missing an assembly reference?
回覆刪除這是我出現的問題,想了很久都不知道怎樣解決.