創作內容

5 GP

[Unity教學] 2D連線小遊戲製作 Part.5

作者:某燕│Unity(遊戲引擎)│2016-12-16 20:56:31│巴幣:13│人氣:3491
這篇會講到

1.製作開頭場景
2.連線的方式與Match Maker


前言:
unity在5.x以後使用了的新的網路連線方法,簡稱UNet

為了解說方便,製作一個遊戲名叫 搶奪20 / Rob20 的連線小遊戲



這篇會讓這個遊戲更加的完整,我們會做一個遊戲開始畫面,並把連線的面版搬拿過去


開頭場景

首先呢我們先新增一個場景命名為title,開始拉畫面吧~~

我希望開頭畫面有一點科幻的感覺,就找了方塊的圖當作背景

在這個網站上有許多免費的自行http://www.fontspace.com/
這裡使用Digital Tech這個字型


畫面拉好了以後~
還要有Network Msg,步驟都跟之前一樣,play那個場景的Network Msg就可以刪掉囉


1.新增一個GameObject,命名為NetworkMng
2.把NetworkManagerment 和 HUD掛上去


接著把NetworkManagerment的設定完成

1.File > Buld Setting裡
2.把兩個場景加入編譯清單中
不這樣子等下會跳錯誤喔

1.再把兩個Scene拖到對應的位置,一個Online 一個Offline

unity在離線的時候切到Offline場景,連線成功時切到Onlin場景,離現場景就用title,連線場景當然用play囉

2.最後記得把cvsClient拖到Player Prefab的框框裡


接著為了要讓HUD置中在標題底下,要來新增一個script來控制

在NetworkMng下新增script,命名為SceneControl

把裡面的東西全部砍掉,新增下面的語法

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Networking;
using System.Collections;

public class SceneControl : MonoBehaviour
{
    public NetworkManagerHUD hud;

    void Start()
    {
        hud = gameObject.GetComponent<networkmanagerhud>();
    }

    void Update()
    {
        if (SceneManager.GetActiveScene().name == "title")
        {
            hud.offsetX = Screen.width / 2 - 100; ;
            hud.offsetY = Screen.height - 200;
        }
        else
        {
            hud.offsetX = Screen.width - 215; ;
            hud.offsetY = -50;
        }
    }
}

原理是先抓視窗的長與寬,再計算出他的位置

場景是title的話方在畫面的中下方,場景是play的話就放在右上角


編譯成exe來測試一下吧

順便測試一下功能是不是都ok

1.連線控制面板在開頭場景時的位置
2.連線控制面板在遊戲畫面的位置
3.遊戲流程是否正確
4.輸贏判斷是否正確

如果都沒問題~那恭喜你,遊戲完成囉~(灑花

辛苦各位了,如果對這幾篇教學有甚麼問題的話,歡迎留言討論喔d(`・∀・)b

順便附上完整程式碼

GM.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class GM : MonoBehaviour
{
    public enum Round
    {
        non,
        player1,
        player2
    }

    public enum Process
    {
        start,
        waitLogin,
        decidePlayer,
        p1Action,
        p2Action,
        checkWin,
        end,
    }

    public List<Player> allPlayer = new List<Player>();
    public Round round = Round.non;
    public Process process = Process.start;
    int roundCount = -1;
    public int Mumber = 0;

    public void Login(Player player)
    {
        allPlayer.Add(player);
        player.RpcSetPlayer(allPlayer.Count);

        if (allPlayer.Count == 2)//
            process = Process.decidePlayer;//
    }

    public void AddMunber(int addMun)
    {
        Mumber += addMun;
        if (Mumber >= 20)
            process = Process.checkWin;
        else
            process = Process.decidePlayer;
    }

    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 == 0)//p1回合
                {
                    round = Round.player1;
                    process = Process.p1Action;

                }
                else//p2回合
                {
                    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;
        }
    }
}

Player.cs
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

public class Player : NetworkBehaviour
{
    public enum Process
    {
        start,
        action,
        wait,
        end
    }

    public Image ImgPlayer1;
    public Image ImgPlayer2;
    GM gm;

    [SyncVar]
    public Process process = Process.start;

    [SyncVar]
    public string SysMsg;

    public Button btnAddOne;
    public Button btnAddTwo;
    public Text txtMunber;
    public Text txtSysMsg;

    [SyncVar]
    public int Munber;

    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();
        }
    }

    [ClientRpc]
    public void RpcSetPlayer(int id)
    {
        if (isLocalPlayer)//hasAuthority
        {
            switch (id)
            {
                case 1:
                    ImgPlayer1.gameObject.SetActive(true);
                    break;
                case 2:
                    ImgPlayer2.gameObject.SetActive(true);
                    break;
            }
        }
    }


    [Command]
    public void CmdAddMunbers(int addMun)
    {
        if (process == Process.action)
            gm.AddMunber(addMun);
    }

    public void SetProcess(Process process)
    {
        this.process = process;
    }
}



連線方式與Match Maker

基本上朋友間要互連的話,只要一方開Host另一個打IP進去就可以連線了

這裡再提供一個不使用IP就可以連線的方式

使用Unity提供的Match Maker

那麼第一步~

首先先點那個雲的按鈕


會看到Service的畫面,點multiPlayer


點Dashbord


會跳出網頁,設定玩家人數為2


儲存後回到Unity,這樣設定就ok囉


編譯成exe檔測試一下



開Server的人需要在Room Name的地方打上伺服器名稱,比如說房間1

要連的人按下Find Internet就可以在清單找到房間1

點Join Match:房間1後就連上線囉~


這篇到這裡結束了

感謝看到這裡的你

希望這系列的教學對你會有幫助

感謝大家!!!
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=3416496
Some rights reserved. 姓名標示-非商業性 2.5 台灣

相關創作

同標籤作品搜尋:Unity3D|C#|教學|Unity(遊戲引擎)|Unity(遊戲引擎)

留言共 2 篇留言

sleepever
大推^^
很有用的教學

01-17 16:51

某燕
謝謝~01-21 01:44

請教一下~
為什麼我場景跟code都照做了輸出執行卻沒有玩家連線呢
代表角色的圖片跟+1&+2按鈕也都沒有動靜...

07-27 18:22

我要留言提醒:您尚未登入,請先登入再留言

5喜歡★ericyin322 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:[Unity教學] 2D... 後一篇:塗鴉...

追蹤私訊切換新版閱覽

作品資料夾

ilove487奇幻小說連載中
《克蘇魯的黎明》0667.掉到海裡要先救誰?看更多我要大聲說昨天14:44


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】