Как ясно из названия – я собираюсь показать работу с сетью на основе примера (M2H_2B). Полную версию уроков M2H можно скачать по ссылке . Они все на английском и на JavaScript.

Я перевел три скрипта, необходимых для сборки сетевого приложения, на C#, т.к. C# разработчиков становится все больше :)

Итак:

1. Скрипт подключения к сети “Connect.cs”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
using UnityEngine;
using System.Collections;

public class Connect : MonoBehaviour
{

    public string connectToIP = "127.0.0.1";
    public int connectPort = 25001;

    // Смешанный GUI для сервера и клиента
    public void OnGUI()
    {

        if (Network.peerType == NetworkPeerType.Disconnected)
        {
            //Сейчас мы отключены и не являемся клиентом или хостом
            GUILayout.Label("Connection status: Disconnected");

            connectToIP = GUILayout.TextField(connectToIP, GUILayout.MinWidth(100));
            connectPort = int.Parse(GUILayout.TextField(connectPort.ToString()));

            GUILayout.BeginVertical();
            if (GUILayout.Button("Connect as client"))
            {
                // Подсоединяемся к "connectToIP" и "connectPort" как клиент
                // В данном случае игнорируем NAT
                Network.useNat = false;
                Network.Connect(connectToIP, connectPort);
            }

            if (GUILayout.Button("Start Server"))
            {
                // Создаем север с 32 клиентами используя порт "connectPort"
                // Так же игнорируем NAT
                Network.useNat = false;
                Network.InitializeServer(32, connectPort);
            }
            GUILayout.EndVertical();


        }
        else
        {
            //Мы имеем подключение(я)!


            if (Network.peerType == NetworkPeerType.Connecting)
            {
                // Статус - пдключение
                GUILayout.Label("Connection status: Connecting");

            }
            else if (Network.peerType == NetworkPeerType.Client)
            {
                // Статус - клиент
                GUILayout.Label("Connection status: Client!");
                GUILayout.Label("Ping to server: " + Network.GetAveragePing(Network.connections[0]));

            }
            else if (Network.peerType == NetworkPeerType.Server)
            {
                // Статус - сервер
                GUILayout.Label("Connection status: Server!");
                GUILayout.Label("Connections: " + Network.connections.Length);
                if (Network.connections.Length >= 1)
                {
                    GUILayout.Label("Ping to first player: " + Network.GetAveragePing(Network.connections[0]));
                }
            }

            if (GUILayout.Button("Disconnect"))
            {
                Network.Disconnect(200);
            }
        }


    }

    // ВСЕ функции ниже НЕ ИСПОЛЗУЮТСЯ в данном примере, а приведены только для демонстрации.
    // Сначала убедитесь в понимании кода, приведенного выше в функции OnGUI()

    // Слиентские фукнции, вызываемые Юнити
    public void OnConnectedToServer()
    {
        // Этот КЛИЕНТ подключился к серверу
        Debug.Log("This CLIENT has connected to a server");
    }

    public void OnDisconnectedFromServer(NetworkDisconnection info)
    {
        // Этот СЕРВЕР или КЛИЕНТ отключился от сервера
        Debug.Log("This SERVER OR CLIENT has disconnected from a server");
    }

    public void OnFailedToConnect(NetworkConnectionError error)
    {
        // Не удалось поключиться к серверу
        Debug.Log("Could not connect to server: " + error);
    }


    //Серверные фукнции, вызываемые Юнити
    public void OnPlayerConnected(NetworkPlayer player)
    {
        Debug.Log("Player connected from: " + player.ipAddress + ":" + player.port);
    }

    public void OnServerInitialized()
    {
        // Сервер инициализирован и готов
        Debug.Log("Server initialized and ready");
    }

    public void OnPlayerDisconnected(NetworkPlayer player)
    {
        // Игрок отсоединился от player.ipAddress + ":" + player.port
        Debug.Log("Player disconnected from: " + player.ipAddress + ":" + player.port);
    }


    // OTHERS:
    // Для полного обзора всех сетевых функций вызываемых Юнити
    // следующие четыре так же были добавлены, но они сейчас игнорируются

    public void OnFailedToConnectToMasterServer(NetworkConnectionError info)
    {
        // Не удалось соединиться с мастер-сервером
        Debug.Log("Could not connect to master server: " + info);
    }

    public void OnNetworkInstantiate(NetworkMessageInfo info)
    {
        // Новый объект был создан info.sender
        Debug.Log("New object instantiated by " + info.sender);
    }

    public void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    {
        //Пользовательский код здесь (Ваш код!)
    }
}

2. Скрипт игрока “PlayerScript.cs”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using UnityEngine;

[RequireComponent(typeof(NetworkView))]
public class PlayerScript : MonoBehaviour
{
    public void Awake()
    {
        if (!networkView.isMine)
        {
            // Если не мы владельцы данного объекта, то выключаем данный скрипт.
            // Но помним, что RPC и OnSerializeNetworkView работают в любом случае
            enabled = false;
        }
    }

    public void Update()
    {

        if (networkView.isMine)
        {
            // Только владелец может двигать куб!         
            Vector3 moveDirection = new Vector3(
                Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            float speed = 5;
            transform.Translate(speed * moveDirection * Time.deltaTime);
        }

    }


    public void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    {
        if (stream.isWriting)
        {
            // Выполняется у владельца networkview;
            // Сервер рассылает позицию по сети

            Vector3 pos = transform.position;
            stream.Serialize(ref pos);//"Кодирование" и рассылка

        }
        else
        {
            // Выполняется у всех остальных;
            // Клиенты получают позицию и устанавливают ее

            Vector3 posReceive = Vector3.zero;
            stream.Serialize(ref posReceive); //"Декодирование" и прием
            transform.position = posReceive;

        }
    }
}

3. Скрипт создающий игроков при подключении и удалящий при отключении “SpawnScript.cs”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using UnityEngine;
using System.Collections;

public class SpawnScript : MonoBehaviour
{
    public Transform playerPrefab;


    public void OnServerInitialized()
    {
        Spawnplayer();
    }

    public void OnConnectedToServer()
    {
        Spawnplayer();
    }

    public void Spawnplayer()
    {

        Transform myNewTrans = (Transform)Network.Instantiate(
            playerPrefab, transform.position, transform.rotation, 0);

    }

    public void OnPlayerDisconnected(NetworkPlayer player)
    {
        // Чистим за игроком
        Debug.Log("Clean up after player " + player);
        Network.RemoveRPCs(player);
        Network.DestroyPlayerObjects(player);
    }

    public void OnDisconnectedFromServer(NetworkDisconnection info)
    {
        // При отключении от сервера чистим за собой
        Debug.Log("Clean up a bit after server quit");
        Network.RemoveRPCs(Network.player);
        Network.DestroyPlayerObjects(Network.player);

        /*
         * Запомните, что мы удаляем только наши объекты и не можем удалить объекты других игроков
         * т.к. мы не знаем где они и мы не следим за ними.
         * В игре обычно вы должны перезагрузить уровень или загрузить уровень с главным меню ;).
         * Сейчас мы можем использовать здесь "Application.LoadLevel(Application.loadedLevel);" для сброса сцены.
         */

        Application.LoadLevel(Application.loadedLevel);
    }
}

Я надеюсь функциональность данных скриптов вы поняли прочитав переведенные мной комментарии.

Сборка сцены:

  • Создаем в сцене пустой GameObject и называем его Connect. Вешаем на него скрипт “Connet.cs”. Данный объект будет отображать GUI для подсоединения к сети или создании сервера.
  • Создаем в сцене пустой GameObject и называем его SpawnScript. Вешаем на него скрипт “SpawnScript.cs”. Данный объект будет создавать и удалять данные игроков.
  • Создаем префаб игрока. Для Этого создаем кубик. На него вешаем “PlayerScript.cs” который автоматически ему добавляет компонент “NetworkView”. Перетаскиваем скрипт PlayerScript назначенный кубику на поле Observed компонента NetworkView и устанавливаем параметр State Synchronization в Reliable Data Compressed. Создаем в проекте пустой префаб и перетаскиваем туда наш кубик.
  • Назначаем наш созданный префаб игрока в SpawnScript полю Player Prefab (он должен знать как создать игрока).

Вроде все готово, можно собирать и тестировать. Чтобы тестировать на своей машине, нужно указать юнити, что следует работать в фоновом режиме: Edit->Project Settings->Player->Run In Background

Данный пример демонстрирует работу сети где сервер НЕ рулит :)

Заметки: камера сейчас одна и будет у каждого игрока в том месте, где она установлена с самого начала. Я думаю (не проверял), что для этого в скрипте PlayerScript в методе Awake, если созданный игрок принадлежит текущему сетевому игроку, нужно ее создать и привязать к этому префабу.

Желаю удачи!

VN:F [1.9.3_1094]
Rating: 8.8/10 (54 votes cast)
VN:F [1.9.3_1094]
Rating: +20 (from 26 votes)
Сеть (M2H_2B), 8.8 out of 10 based on 54 ratings

Один комментарий на «Сеть (M2H_2B)»

  1. Armando

    lewisohn@dora.progandist” rel=”nofollow”>.…

    спс….

    VA:F [1.9.3_1094]
    Rating: 5.0/5 (1 vote cast)
    VA:F [1.9.3_1094]
    Rating: 0 (from 0 votes)

Ваш отзыв

Вы должны войти, чтобы оставлять комментарии.



Страница 1 of 0