Please use this identifier to cite or link to this item: https://er.chdtu.edu.ua/handle/ChSTU/9170
Full metadata record
DC FieldValueLanguage
dc.contributor.advisorПервунінський, Станіслав Михайлович-
dc.contributor.authorЧуплий, Максим Андрійович-
dc.date.accessioned2026-03-27T21:48:42Z-
dc.date.available2026-03-27T21:48:42Z-
dc.date.issued2023-06-17-
dc.identifier.urihttps://er.chdtu.edu.ua/handle/ChSTU/9170-
dc.description.abstractАНОТАЦІЯ Чуплий Максим Андрійович; Програмне забезпечення кооперативного ігрового мобільного додатку на основі Unity; 121 Інженерія програмного забезпечення; Черкаський державний технологічний університет; Черкаси, 2023; мобільного Кваліфікаційна робота присвячена розробці кооперативного ігрового мобільного додатку на Unity. Метою є розробка та проектування. Основна ідея роботи полягає в розробці мобільного програмного забезпечення на Unity яке буде дозволяти грати разом кільком людям без доступу до глобальної мережі інтернет, використовуючи функцію "'Портативна точка доступу Wi-Fi", або підключення до іншої спільної локальної мережі. В роботі було виконано: 1 Створено мобільний додаток. 2 Реалізована можливість гри по локальної мережі без доступу до інтернету. 3 Створено поведінку геймплею, який буде поглиблювати гравців в гру. Також була створена архітектура додатку яка дозволяє з легкістю додавати нові та змінювати існуючі елементи гри. Робота складається з трьох основних розділів, додатків та списку використаних інформаційних джерел.uk_UA
dc.description.abstractANNOTATION Сhuрlуі Maksym Unity-based cooperative gaming mobile application software; 121 Software engineering; Cherkasy State Technological University; Cherkasy, 2023; The qualification work is dedicated to the development of а cooperative gaming mobile application on Unity. The goal is to develop and design. The main idea of the work is to develop mobile software on Unity that will allow multiple people to play together without access to the g1oba1 internet network, using the "Рortable Wi-Fi hotspot" feature or connecting to another shared 1ocal network. The following tasks were performed in the work: 1 А mobile application was created. 2 The possibility of playing over а local network without access to the Internet was implemented . З Created а gameplay that will deepen the players' engagement in the •game. Also, the application architecture was created that allows for easily adding new and modifying existing game elements. The paper consists of three main sections, appendices and а list of references.uk_UA
dc.language.isoukuk_UA
dc.subjectUnityuk_UA
dc.subjectкооперативна граuk_UA
dc.subjectмультиплеерuk_UA
dc.subjectмобільний додатокuk_UA
dc.subjectгеймплейuk_UA
dc.subjectінтерфейс користувачаuk_UA
dc.subjectрозробка гриuk_UA
dc.subjectлокальна мережаuk_UA
dc.subjectUnityuk_UA
dc.subjectcooperative gameuk_UA
dc.subjectmultірlауеruk_UA
dc.subjectmobile applicationuk_UA
dc.subjectgameplayuk_UA
dc.subjectuser interfaceuk_UA
dc.subjectgame developmentuk_UA
dc.subjectlocal networkuk_UA
dc.titleПрограмне забезпечення кооперативного ігрового мобільного додатку на основі Unityuk_UA
dc.typeBachelor Thesisuk_UA
Appears in Collections:121 Інженерія програмного забезпечення (Інженерія програмного забезпечення)

Files in This Item:
File Description SizeFormat 
Кваліфікаційна робота бакалавра Чуплий Максим Андрійович.pdf
  Restricted Access
23.79 MBAdobe PDFView/Open Request a copy


Items in DSpace are protected by copyright, with all rights reserved, unless otherwise indicated.

Extracted text
MlHICTEPCTBO ОСВІТИ 1 НАУКИ УКРАЇНИ 
ЧЕРКАСЬКИЙ ДЕР)ІСАВНИЙ ТЕХНОЛОГІЧНИЙ УНІВЕРСИТЕТ 
Факультет інформаційних технологій і систем 
Кафедра програмного забезпечення автоматизованих систем 
ПОЯСНЮВАЛЬНА ЗАПИСКА 
до кваліфікаційної роботи 
«бакалавра» 
освітній рівень 
на тему: Програмне забезпечення кооперативного ігрового мобільного 
додатку на основі U11ity 
Виконав: студент 4 курсу, групи ПЗ-1904 
Спеціальності 
121 «Інженерія програмного забезпечення» 
(шифр і назва напряму nідrотоюш) 
Студент Чуплий М.А. 
(прізвище та і 11іц іал11) 
Керівник Первунінський С.М. 
(прізвище та ініціала) 
Рецензент Біда А. Ю. 
(прізвище та ініціали) 
Черкаси 2023 
Чер~-nськ1111 держnвнніі т~-хно.1огіч1111і1 \'Ніверс1пет 
Ф:11-:уль~т ін rjюрм,щіііннх технологій і с11с~~1 
К:tфедрn 11р()rр:1111нОГ\) зnfіезпечення nнто:\шт11зо1шю1х с11стем 
Освітніії рівень ..!6!:зu~.:~а·!:л::L!.а:;!.Ев~-----------------------------
Спеціальність ) ? ) «rн женерія щщrрамноrо заб?ЗПеченнsш 
Освітня програ.ма Інженерія проmамного забезпечення 
Зав. к 
Голvб С. В. 
ЗАВДАННЯ 
НА КВАЛІФtкАЦІЙНУ РОБОТУ СТУДЕНТУ 
Чvnлнй Максю.1 Анлрійов11ч 
(прізвнще, і.,1·я. по бать~,.-ові) 
1..Тему проек--rу (роботи) Програмне забезпечення кооперативного іrрового мобільного 
лодаТК\' на основі Unitv 
Керівник проеюу (роботи) Первvнінський Станіслав Михайловпч ц тн, професор 
(прізв11ще, і~1·я , по батькові, нау1;овш1 С1)'Піш,. . вчепе звання) 
Затверджені наказом Черкаського державного технологічного університету від « 24 » лютого 
2023 рокv N°43/04 
2. Строк подання студентом проекrу (роботи) 9 червня 2023 р. 
З. Вхідні дані до проеh"І)' (роботи) стандарти програ?-.-mого забезпечення: процеси vnравління: 
вимоги до прое1..'Т\/: каленларне планvвання nрое:ктv: vnравління ризика.~-ш проекгv: 
vправлjння ресурсами 
4. Зміст розрахунково-пояснювальної записки (перелік ШІтань, лкі потрібно розробити) 
Вступ: Існуючі методи та засоби розв'язання поставлеm-1х завпань: 
Проектування програмного забезпечення систеl\-rи : 
Розробка та тестvвання програмного забезпечення: 
Реалізація та впровадження результатів: 
Висновок: 
Список використаних джерел: 
Додаток А. Специфікація 
Додаток Б. Лістинг програми Додаток 
Додаток В. Інструкція користувача Додаток 
Податок Г. Графічні матеріали 
5. Перелік графічного матеріалу (з точни~,-r зазначенням обов'язкових робіт проекту); 
Діаграма класів; 
діа02ама пакетів: 
Діаграма компонентів: 
Діаграма розгортання: 
Діаграма діяльності: 
• 
6. Консультанти роздшш проекту Р 
Під111-1с, ;ц1т11 
Прізвище, ініціали та rюсnди 
Розділ За~щ1111 ІІН 131 І,Ц:ІВ За1щш11 1}1 1 1 р щ 
І<ОІІСУЛІ>ПІІІПІ 1 11)1 
І 
2 
з 
7. Дата видаt1і завдав нл .f2a14~\!fІCU:DШBШHl1!Я..J2.:i0~2~3_Jp2,., ____________________ _ 
КАЛЕНДАРНИЙ ПЛЛН 
Стrок 
Ш І КОШІ 111 ІН 
№ 
Назва етапів випусююї робот11 стшІів Пр1щі•1 
п/п UІІІІУСЮІОЇ 
r0Goп1 
-
І Постановка задачі 05.12.2022 Ul\l(OJЩ 
-
2 Підготовка завдання 13.12.2022 1.1111-:ОІЩ 
з Погодження завдання І 6. 12.20?2 !3ІІКОІЩ 
4 Затвердження завдання 17.0 1.2023 ІНІКОІІі1 
Ос1-1ов1rа спщін 
І Підбір матеріалів 02.02.2023 ВІІКОІІЩ 
2 Аналіз шляхіn вирішення поставленої задачі 27.02 .2023 ІШКОІІЩ 
з Розрахунок основних параметрів роботи 09.03.2023 ВІІКОІІ:11 
4 Вибір кінцевого ваоіантv проект1юrо оіше1111я 17.03.2023 ВІІКОІІЩ 
5 Оформленнн первісної редакL1ії роботи 28.03 .2023 UІІКО ІІаІ 
. 
Заклю1ша стадін 
І Узгодження прийнятих 11рое.1п1111х р1ше11ь з І 0.05.2023 1шко11а1 
керівником 
2 Оформлення пояснювnльної записки роботи в 19.05 .2023 DIJKOll:l/ 
кінцевій редакції 
з ПоГІеоедній захист ооботи 22.05.2023 ВИ1<0 11 '1 ІІ 
4 Затвердже1шя ооботи 29.05.2023 
5 Рецензування роботи О 1.06.2023 
6 Захист роботи 12.06.2023 
Студент Чvплий М . А . 
(np i'JOIIUIC т;:s ІІІЩІJ.111 ) 
Керівник проекту (роботи) Пепвv11 і 1 1с 1,ю 1 іі С. 1. 
( llfl/11111111~ 1,1 ІІІЩІJ. 111) 
АНОТАЦІЯ 
Чуплий Максим Андрійович; 
. 
Програмне забезпечення кооперативного 1rpoвoro мобільного 
додатку на основі Unity; 
121 Інженерія програl\•ІНого забезпечення; 
Черкаський державний технологічний університет; 
Черкаси, 2023; 
Кваліфікаційна робота присвячена розробці кооперативного 
1rрового мобільного додатку на Unity. Метою є розробка та проектування. 
Основна ідея роботи полягає в розробці мобільного програмного забезпечення 
на Unity яке буде дозволяти грати разом кільком людям без доступу до 
глобальної мережі інтернет, використовуючи функцію "'Портативна точка 
доступу Wi-Fi" , або під1шючення до іншої спільної локальної мережj. В роботі 
було виконано: 
1 Створено мобільний додаток. 
2 Реалізована можливість гри по локальної мереж~ без доступу до 
штернету. 
3 Створено поведінку геймплею, який буде поглиблювати гравців в 
гру. 
Також була створена архітектура додатку яка дозволяє з легкістю додаватн 
нові та змінювати існуючі елементи гри. 
Робота с1шадається з трьох основних роздшш, додатюв та списн:у 
використаних інформаційних джерел. 
Ключові сліва 
Uпity, кооперативна гра, l\•1ультиплеер, мобільний додаток, rеймплей, 
інтерфейс І<ористуnача, розробка гри, локальна мережа. 
ANNOTATION 
СlшрІуі Maksym 
Uпity-based coopeгative gашіпg mobile application software; 
121 Softwai·e engineeriпg; 
Che1·kasy State TechnologicaJ Univeтsity; 
CheI"kasy, 2023; 
Tl1e q11alificatio11 work is dedicated to the developmeпt of а coopeгative 
gaming шоЬіtе app\kation on Uпity. Tl1e goa] is to develop and desigп. The main 
idea of tl1e woгk is to develop шоЬіlе softwai·e 011 Uвity that will allow multiple 
people to play together witl10ut access to the g1oba1 inte111et network, using the 
"РшіаЬlе Wi-Fi hotspot" fеаtнге ог co11necti11g to anot11eг sha1·ed 1ocal пetwork. Tl1e 
follo"viпg tasks wеге perfo1111ed i.n tl1e woгk: 
1 А nюbile appli'cation was created. 
2 The possibility of playing оvег а local network witl10t1t access to the Interпet 
was iшplemeпted. 
З Cгeated а gaшeplay that \Vill dеереп tl1e playeis' engagement іп tl1e ·gаше. 
Also, tl1e applicatioп а1·сЬіtесtш·е was cгeated t]1at allows fог easily adding пеw 
апd modifying existing game elements. 
ТЬе paper coпsists of three main sections, appendices and а list of references. 
Keywords 
Uпity, cooperative game, шпІtір]ауег, mobile applicatioп, gшneplay, useг 
intei-face, game development, local пetwo1·k 
31\-ІІСТ 
ПЕРЕЛІК УМОВНИХ С.КОРОЧЕНЬ ................................................................................. 4 
ВСТУП .............................................................................................................. ..................................................................................................... ........................... 5 
РОЗДІЛ 1. ................................................................................................................................. 8 
ІСНУЮ'П 1\'lЕТОДИ ТА ЗАСОБИ РОЗВ'ЯЗАННЯ ПОСТАВЛЕНИХ ЗАВДАНЬ .... 8 
1. І Актуальні проблеми, що виникають в процесj розробки .......................................... 8 
І .2 Методи та засоби, які вже використовуються для вирішення проблем під час 
розробки ................ ...... .. .................... ............. ........... .................... ...... ............ ... ................ J. О 
1.3 Огляд існуючих аналогjв .............................. .......... ................................................. . :. 13 
1.4 Конкретизація завдань роботи ............ ....... ........... ................. ................... .. ........ .. .... . 14 
РОЗДІЛ 2 ................................................................. ............................................................... 15 
ПРОЕКТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ СИСТЕМИ ....................... 15 
2.1 Моделювання предметної області ................... .. ................... .......... ....... .... ........... ... .. 15 
2.1.1 Предметна область моделювання. Модель предметної області . Словник 
прещ1етної області ................................_ .. .. .... ... ........................... ...... ........................... 15 
2.1.2 Елементи моделювання предметної області; ..... .......... ............................ .. ..... ... 16 
2.1.3 Робоча область моделювання ........... .................. ......... ....................................... 17 
2.2 Формування та аналіз виr.1ог. ......... ...... ................ ....................... ... ...... .. .. ................ .. І 8 
2.2.1 Формування вимог до програмного забезпечення .... ....... ... ............................. 18 
2.2.1.1 Первинні і детальні вимоги ..... ......... ..... .................. ............ .. ......................... . 18  
2.2.1.2 Вимоги замовника і розробника. Функціональні та нефункціональні 
ВИІ\fОГИ. ...... .... ... . . ..... . . .. .. ...... .... .... ... .. . . .. ..... .... .. . ...... .. . .. . .. . .. . ..... . ..... ... . ........ . ........ ........... 19 
2.2.2 Формування вимог за допомогою діаграми прецедентів ..... .. ................ .. ....... 20 
2.3 Проеюування логічно1· структури програмного компле1<су .. .. ....................... .. .. ..... 23 
2.3.1 Діаграм1'f КJJасів ........................................................ ... .... ... ............... ................... 23 
2.3.2 Діагр8.},,ІИ пакетів ... ..... ...... .. ................................. ............ .... ... .............................. 26 
2.4 Архітектурне проектування ........ ... ... ... .......... ................... .................... .... ... .... ........... 26 
2.4. І Д1а.г раl\Іrа компонент1.в  ..... ... .... .. .... ............. .................. ...... ..... ......................... .... ?_ б 
2.4.2 Розгортання програмної системи на апаратних засобах. Діаграма 
розгортання. . .................................................... .............. ............................................... 28 
, І 
ЧДТУ 231926.011 ПЗ 
.ім Лист №документа Пщn-нс Дата 
JJoзpoo. чуплии М. А. ~ JІІТ. ли1.,"Г J/истш. 
Керtвн нк нервуншськнн L . .м. Програмне забезпечення 
r,f✓?Щ' t; І LнJ L J j) 
кооперативного1грового 
-- /'і 
Н. контр. П1вень V. Б. .мобільного додатку на ФІТІС, 
Іf7&5j_ 
Затв. Голуб С. В. основі Unity Кафедра ПЗАС, ПЗ-1904 
? 4 1 д1·агр<> .. 1а 1..•оt-шонент1·в ................. ............ ... 26 
- . • (U~ 1, • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • · • • • • • • • • • • • • • • • • • • 
2.4.2 Розгортання програмної систе:ми на апаратних засобах. Діаграма 
розгортання ................................................... ....- . . . . . ..  .. .  .. . .  .. .  ..  .. .  .. .  .· ·········· ········· ··· .. •········ ··28 
2.5 ~{оде.І"Іювання поведінки системи .... ....... .................................. ... ..... ............... ...... .... 29 
2 . 5- . 1 д1·а"г ра"" 1а д!· ЯЛ ь Н ос n · .. ................................ ...... .. .... ·· · ·· · ·· ·· · · · ..... .... .................... .. ... 29 
-?•  5 • ?-  д1·аrр"U"J.H" а посл·1 довност!· •• •• ••••••• . . . . .. •• . .. ...... .... ,. • • •• •• • •• • • • •• • • • •••• • • ................. .......... .. 32 
_-, .:-, . ...,,  д1· arpal\1a · ... 
коl\1уюкац11 .................... ........ .. ................... ........ ... .. •· •• ·· · •• · •· •· ·· ·· ·· ·· · ··· · · · 33 
2.5.4 Діаграма скінченного автомату ..... .......... ....................... ........ ............... .. .... ..... .. 34 
роз~т·п л 3 ........... ···•··············•···················•·· ............................................... . ............................ 35 
РОЗРОБКА ТА ТЕСТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ ...................... 35 
3. І Розробка програмного комплексу ......... ...... ..... ............................ ......... .. ..... ... .......... . 35 
3.1.1 Обrрунтування вибору засобів реашзацн ... ..... ....... .... ................. ........ ... .......... 35 
3.1.2 Опис структурної (функціональної) схеми ....... ... ... ..... .............. .. ..... .............. .. 38 
3.1 .3 Опис логі'<Шої схеми системи ......... .. ............. ........ ...................................... ....... 40 
3.1.4 Розробка бази даних .. ................... .................. ... ..... ........... ....... .. .... .. ........ .... ..... . 40 
3. l .5 Розробка інтерфейсу користувача .. .......... ..... .... ..... ..................... ........... ... ... ... .. .41 
3.1.6 Опис розробки прогрш-mих компонентів ......... ...... .. ..... .. .............. ........... ........ 44 
3.2 ТесТ)rвання системи ....... .......................... .... .. ..... ......... ...... ......... .. .............. ........ ........ 46 
3.2.1 Іv1оду:л:ьне тестування ........................ .............. ... ...... ................................. .. .... .. .. 46 
3 .2.2 Інтеграційне тестування ........ ..... .... .......... ...... .................. ..... .... ... ......... ... ...... .... 50 
3.2.3 Системне тестування ... ...... .. .. ................ ....... ........................ ..... .... ................ ... .. 51 
3.2.4 Приймальне тестування .... ........ .... .... ...... ................ ...................... ... .................. 52 
З.З Впровадження програмного комплексу .......... .... ... .... ... ... ....... .. ... ...... ...... ..... ... .. ....... 53 
3.3.1 Розгортання системи ..... .. ... ... ... ...... ................... ....... ... ... ...... .. ........ ........ ............. 53 
висновок .......................................................................................................................... 55 
СПИ'СОК ВИКОРИСТА.І-ІИХ" ДЖЕРЕЛ .............. .. .......................................................................................................................... .. ........ 56 
ДОДАТОК А .......................................................................................................................... 58 
ДОДАТОК Б .......................................................................................................................................................... 60 
ДОДАТОК В ........................................................................................................................... 120 
ДОДАТОК г ........................................................................................................................................................... 123 
ЧДТУ 231926.011 ПЗ 
ЧДТУ 23 І ()2 (,,() J І rn 
lf EPEJIIJC УМОВНИХ CJCOl'OЧEJH, 
U11ity і1 ·роІJИЙ )ЩИІ'УІІ 
Міпо1· мсrсжсни біб;1іот~ю1 JІJІя Unity 
ооп об'скrно орієнтоване 11рuграмунання 
коп 1<0мгюнентно орієнтоване програму~аннн 
DI впровадження залежностей 
LAN локальна мережа 
Wi-Fi бездротовий мережевий протокол 
Prefab nередбудований об'єкт в Unity 
Scene сцена в Unity 
АРІ інтерфейс програмного забезпечення ( appJication 
progra111шing interface) 
4 
ЧДТУ 23 1926.0 І. І ПЗ 
НСТУП 
А1,ту1шь11ість тем11: З розш-п1<0м технологій та пошнреншrм мобілмrнх 
пр11строїв. прогрнмування мобіп1,11нх дuдат1сів стає осе більш важливою ти 
перспею·нвною галуззю. Нині на риш<у існує безліч різноманітних мобільних 
додатків, інтерфейс та 1\-Южлиnості яких залежать від специфіки їхнього 
призначення. Розроб1,а ігрових мобільних додатюn є однією з найбільш 
популярних галузей у мобільній розробці, і це пов'язано з тим, що ігрові 
додатки приваблюють велю<у кількість 1сористувачів та мають потенційно 
великий риноl(. 
У програмуванні кооперативних 1гроnих мобільних додатС<ів виникають 
специфічні проблеми, пов'язані з взаємодією гравців між собою та з сервером, 
синхронізацією даних та оптимізацією роботи додатка. Для успішної розробки 
та підтримr<И гри потрібна глибш<а експертиза у сфері програмування, зоr<рема 
знання мов програr-.,1ування, алгоритмів та структур даних, а також пра1<тичний 
досвід розробки мобільних додатків та ігор. 
lVIeтa і завдання розроб1си: Мета розробки програмного забезпечення 
кооперативного Ігрового мобільного додатку полягає в розробці 
функціональностj, яка надасть користувачам можлив.ість взаємодіяти між собою 
на l\Юбільних пристроях. Завдання розробки програмного забезпечення 
кооперативного ігрового мобільного додатку вrшючають наступні кроки: 
1 Розробка дизайну та jнтерфейсу 1юристувача: розробити інтерфейс 
користувача, яr<ий буде зручним і простим у використанні для гри на мобільних 
пристроях. 
2 Проектування ПЗ: розробити архітектуру програмного забезпечення 
яке буде надавати простоту при створенні нових функцій. 
З Розробка логіr<и гри: розробити логіку гри, щоб користувачі могли 
взаємодіяти між собою. 
4 Розробка серверної частини: розробити серверну частину додатку, 
яка буде відповідальна за обробку вхідних даних та їх передачі іншим клієнтам. 
5 Тестування та відлагодження: виконати тестування додатку та 
5 
1 І J ІІ V J ll 1 І J r,Ufl lJ: 
1\ІtІ • І 1І1t1 1 ІФІ • ІІІРІ ІІ•• ! ІІІІІ ІІ І ' . 111, j ІІННІІІІr/ІІІ II ІІі /І 'fll t І ' l 1 1/ 11 І lfffHI , 
r, ,l \ ,,Іt't t, І• /ІІ V ІІ!ІІІІІІ/ J ft1І•yf,11( • /ll :fl1І І/II ІЩJІ J/(1ЩІІkУ ·111 іІІІ/1"1<.;ЮН І<U/)tУГІ{ИЙ 
11111 1 1 \ 1\• І ІІ• ІІІ1111,1 1 1 у ІІІ 1111 ,,, ,/ІіІІІІ //ІНІ 10 ,рщ f УІІ І І'fіІІ . 
, , 11111,,,11 ,111 1 І ІІІІІt ІІІІ ІІ ІІ// Н І 1111, ·11 111,1 11111 1, МІ 1 ' r,y, 11 1ю· i11of111c 11111J 11rо1 ·r11м 11н І-і 
111 11 111,;1, 1. 11 1, 1111 1,1r11 І11t" 1 у 11,1 1111.1 1 • 1,111111 111111і l' ІІ , ІІї111Мо;(ії 1t<фІІL; 1 у 11а1 1і11 міжсоuuюjа 
,н,,11 1 11\11 1 11111 1 І р1111 ,1 1щ,r,1, 11 , 1111 к 11\JІН ' Ірин к . 
С Н'І ' с І ~ 1 ~ннрнfіюн 1'11·1i,1,r11(11 1111111 р1,м11и1 (J ' і11Gс. ·юсчс11 ІІS 1 коо11сrати1111ого 
І ІІ 111111!1 І І ll tl ,0 1111,1111111 J I,( 1Jt1t·11cy, 
1\1 І' І НІНІ ЩНН'І~ 1 у 11 11H IIJI 'J'JI ІШІІt'І JJУЮНІІІІШІ : /J.)/Sf /НІ /СО ІІШ ІШІ І fO(;.T<.lUJICIIИX 
111,111111 nv, 111 'lfll' l lll'\1111111! ·111111 М~ ІЩ(ІІ РtJ' } ІЮ(Ї І(І І : оu't:кпю тн І<ОМ /101/СІІТJІО 
І І \ 111 ІІІ І ІІ\І ІІ Н 1 І ІрОІ l lllr.І,Yflfl llll/i , l\riL; І IJLII у 1нt І/Ш/ , М()J(СJІІUН!1 1/ШІ , ІІрU' І 'U'/' ИІІУUШ ІШІ , 
1,,,1, 111 1 ' t1\HІL'p1111 11рхІн~ 1(' 1 ур11 . 
с )11щ· с, · 11н~м 1ш11 х 1н•·1у.1 11 :1 si1 Ін : 11 і t:юІ рmр(1бки 11ро1·rнм1югu :юбс:тсч<:;1111я 
1,1111 11 t•J111111111tt1'{ мо( 1 ІJІ 1 , 1111ї I р11 11 рнм1тх ю11 1 1 1uм 11uї роботи бу;ю отримано 
11,1· 1111'11І111І рс · 1ут:1 11 ·111 , 11to ,r ію 11ср1 1.жун,т1. лоці111 , 11іст 1, та шпуаш,11ість ро·>робю1 
ТІІІПІІ 'ІІ ' І'ІІІІ У і 1 ·ор , O l' l/(111111 р1.пут,·1·1п11 мо,І(ІІ lІ У'ІНГШІLІІИ'/'11 1ш<.:тун11им L/11ІІОМ : 
І 'tІ ' І ІіР 1J І t JІ (І 1ш1н1ср11т1ш11у мuGim,11 y 1 ·ру ~ н111юрис1·ш1ш1м платформи 
\ J111Іу п1 ~1111111 11pt11 р11му111111ш1 СІІ . 
;1 І І11І~РІНІ t:'І 11110 ;~ot:I1·11, t.: 1(J 1 tщ11y і ю-11rнмі•111у 1 ·рафі1Су. 
:1 ' J 11L''lll t: Olll\lІO і 111 у'(ти 1111 1, 'Jро·іум і11и~і та :~руL111ні1 інтсрфсі,іс, що 
н11 · 11111J 1,11 · 1~01н1 ~ту 1111 1 111м нс1 · 1<1..1 орk11ту 11н· 1 ·нt:s1 в 11-,і та юасмодінти між собою. 
1\ У~11і1111ю і11тс1 'J'Ю ІJІІІЮ рі·,11uмш 1іт11і фу111щії тu фічі, що 11ідвищують 
1 ·с І\І"І ІІІ J І С І\ І \НІ ТІ\ JtoHIII\J'l'l1 рі 'JІІОМLІІІі'І'ІІUСТL, 
5 І Іротсt:то1н1110 Іl)У ш1 рі ·нюмш1іт11их 11ристронх ·1·а відзІJачено високу 
L"І'ІІ\ІІJІІ, ІІ іL:' І 'І, ·111 111111-1;t1<it:'l'IJ роGоти ІНІ 111-tx. 
О'І') І< с.\ МlJїІС ІІІІ · 1рu(і 1-11 ·н 1111 1.: 1ш11шс 1 що p1)'JpuG1ca коонеративної мобіш,ної гри 
' І ІІІІІ<І)ІНІ L' ' І 'ІІІІШІМ ІІ JНІТфорМ І·І tJ1til y 'f'tl мони 11ро1 ·рамуuа11ш1 С# Є дієвим 
і 11 ~трумс1пом нт1 ст11оро1111,1 1tі1ш1н~ х ·п1 дн11аміч11их ігрових прое1стів, що мають 
11сн 111<1 1 І-І 1ютс111tіш 1 у рі 'JІІІ·І Х 1,; 1\н.:рн х. 
с. 
ЧДТУ 231926.011 ПЗ 
Пр.~кт11,111е з1шчс1111s1 оде1>жа11их результатів; розроблене програмне 
}абе'3nечення може бути використане для розваг і відпочинку 1<ористувачів 
мобіл1,них пристроїв. Гра може бути запропонована для завантаження в онлайн 
маr3з1нн,х додатків, де 1<0ристувачі мобільних пристроїв можуть отримати 
доступ до гри та насолоджуватись її геймллеєм. 
Крім того, розробка програмного забезпечення rюоперативної мобільноТ 
1·ри дозволяє розширити можливості технологій мобільної розробки та 
підnищнти рівень еr<спертизи та практичного досвіду у сфері розробки 
мобільних додатків та ігор. Отримані результати можуть бути використані для 
подальшого розвит1<у інших мобільних додатків та ігор, що розширює 
можливості ринку мобільних додатків та забезпечує зростання інтересу до цієї 
галузі розвитку технологій. 
7 
ЧДТУ 231926.О 11 ПЗ 
помилки. Як наслідок, код, написаний для старіших версій Uпity [l], може 
ви~юристовувати застарілі методи або залежності, які більше не підтримуються 
в новіших версіях. Другою причиною є те, що Unity (J] може використовувати 
залежні бібліотеки, такі я1с бібліоте1си сторонніх виробників, які можуть бути 
підключені до пpoercry. Ці бібліотеки також можуть використовувати свої власні 
версії залежностей та АРІ, що може призвести до конфліктів з іншими 
залежностями, які використовуються в проекті. 
Для розв'язання проблеми сумісності 1<0ду гри на Unity [ 1] , 
рекомендується використовувати версію двигуна, яка є найбільш стабільною та 
шдтримується розробниками. Також необхідно перюдично оновлювати 
залежності та бібліотеки, які використовуються в проект~, для забезпечення 
сумісності з новішими версіями Unity [І ] . 
Управління ресурсами: Управління 1гровими ресурсами, такими як 
ассети, є важливою проблемою при розробці мультиплеєрної гри на "Unity [1]. 
Ассети можуть включати в себе те1<стури, звукові ефекrи, ЗD-моделі, анімацію 
та інші елементи гри, що впливають на її геймплей та візуальний досвід. 
Однією з основних проблем управління ігровими ресурсами с збільшення їх 
кількості з часом. У процесі розробки гри , розмір та кількість ресурсів 
' 
збільшується, що може призвести до зменшення продуктивностj гри. Окр ім 
цього, неефективне управління ресурсами може призвести до надм1рноrо 
використання оперативноt" пам'яті та збільшення розміру гри, а також 
незаплановане завантаження ассет1в може призвести до зниження 
продуктивносп під час гри. Інша проблема полягає в тому, що управшння 
ассетами може бути складним завданням, особливо в тому випадку, якщо гра 
містить багато різних ассетів. Розробники повинні мати чіткий інвентар ассетів 
та систему управління ними, щоб забезпечити ефективну роботу з ними. Існує 
також проблема синхронізації ассетів між різними клієнтами та серверами у 
мультиплеєрних іграх. Це може виникнути через відмінності у версіях ассетів 
або в тому, що гравці мають доступ до різних ассетів, що може призвести до 
некоректної роботи гри. 
9 
ЧДТУ 231926.О l 1 ПЗ 
Синхронізація : Синхронізація є однією з ключовнх проGл~м пр11 розробці 
мультиплеєрної гри на Uпity [І]. Синхронізація означає збіг даннх між різ1-1им11 
гравцями У грі, щоб забезпечити однакову гру для всіх гравців. Однак, ue 
завдання не так просто, як здається на перший погляд, і шшию~ють деякі 
проблеми, які потрібно вирішувати. Однією з основних проблем є затрн1''1КИ 
мереж~, що можуrь вплинуrи на шв~,щкість синхронізації між гравцями. Це 
може призвести до проблем зі синхронізацією рухів і дій гравців . Ще однією 
проблемою є взає.модія гравцш з об'єктами в грі, такими я~, предl\1 ети, 
перешкоди та інші ігрові об'ЄЕ\"ТИ . Якщо гравці і\1ають різні в ідображення цих 
об'єктів, це може призвести до проблеr,.,1 з синхронізацією, що призведе до 
неправильної гри. Іншою проблемою є необхідність передачі великої кількості 
даних між гравцями. Це може викликати затримки при синхронізації, що 
призведе до нестабільної гри. Крім того, передача великої кільrюсті даних може 
вплинути на швидІ<ість мережі, що призведе до додаткових проблем зі 
синхроюзац1єю. 
1.2 Методи та засоби, які вже ВІш:ор11стову10ться для вирішення 
проблем під час розробки 
Для вирішення проблем оптимізації коду гри на Unity [ 1] можна 
застосовувати різні методи та техніки, ЗО[(рема: 
Зменшення КІЛЬКОСТІ ВИКЛИКІВ .метод1в : можна використовувати 
кешування результапв методrn, зам1сть повторних виклиюв, а також 
використовувати методи з меншою складністю обчислень, коли це можливо. 
Оптимізація алгоритм1в оброб1ш даних: можна використовувати більш 
ефективні алгоритми, які вимагають менше ресурс1в, а також застосовувати 
асинхронні операції для розподілу обчислювального навантаження між різними 
потоками. Правильне використання ци1<лів та методів: потрібно униr<ати зайвих 
вкладених циклів та методів, а також використовувати ефективні методи 
доступу до даних . Покращення організації пам'яті: можна використовувати 
пулінг об'єктів для ефективного управління пам'яттю та використовувати 
групування об'єктів та даних для зменшення зайвого використання пам'яті. 
10 
ЧДТУ 231926.01 1 ПЗ 
Для реал ізації uих 1етодів южна використовувати документацію Unity 
[ І ], форуми та спіль11оти розробників , а також плагіни та і11струме11ти для 
а11ш1ізу та оптимізації коду, такі як Unity Profiler (І] . 
CPU Usage Profi ler - це модуль Unity [ l ], який дозволяє відстежувати 
використання проuесора в режим, реального часу та аналізувати його для 
виявлення проблем продуктивності гри . 
Основна функція CPU Usage РгоfіІег - це відстеження виконання функцій 
в коді вашої гри та ідентифікація проблемних ділянок. Він показує, які функції 
виконуються, сюльки часу вони займають та який відсоток часу 
використовується на І<ожну з них. Використовуючи цю інформацію, можна 
виявити проблемні функції та зосереди'1 ися на 1·х оптимізації. 
Крім тоrо, CPU Usage Profi1er дозволяє відсл ідковувати юльюсть 
виконуваних ітерацій циrшу за одну секунду, ресурсовживаюч:1 функції, 
покрокове відлагодження та багато іншого. Цей інструмент допомагас 
ідентифікувати джерела затрат, що призводять до зниження продуктивності гри, 
. . . . . . 
1 дозволяє вщсшдковувати ршень продуктивносп в реальному час1. 
Для користування CPU Usage Profi ler необхідно відкрити ВІ<Ладку Profileг 
у Unity Editor і натиснути кнопку Rec01·d. Після цього відбувається запис 
профілювання, п ісля чого можна анал ізувати результати. Використовуючи CPU 
Usage Ргоfі1ег, також можпа ідентифікувати проблемні ділянки коду та вжити 
заходи для їх оптимізації, що локращить продуктивність гри. 
Unity є однією з популярних платформ для розробки мобільних додатків. 
Перш за все, щоб забезпечити сумісність додатка на основі Unity з різними 
мобільними платформами, необхідно використовувати версію Unity, яка 
підтримує платформу, на яку ви хочете спрямувати свій додаток 
Найпоширеніші мобільні платформи, які підтримуються Unity, це Android 
та iOS. Щоб забезпечити сумісність з Andгoid, ви повинні налаштувати проект 
Unity, використовуючи Andгoid SDK та NDK [З], і встановити потрібну версію 
JDK. Для сумісності з iOS необхідно встановити Xcode [4 ] та виконати 
налаштування проеr<Ту Unity для iOS. 
11 
ЧДТУ 231926.01 І ПЗ 
Крім того, при створенн1 додап<а на основі Unity для мобільних 
платформ, необхідно враховувати обмеження апаратних засобіо та інших 
особливостей платформ. Для забезпечення оптимальної продуктивносп та 
швидкодії додап<а, рекомендується виrюристовувати оптимізовані 
налаштування, такі як сrшадність графіки та роздільна здатність екрану. 
Окрім цього, при розробці мобільного додатка на основі Uпity, необхідно 
враховувати різні версії операційних систем, що підтримуються платформою. 
Для забезпечення сумісності додап<а з різними версіями операційної системи, 
можна виr<ористовувати умовний компілятор, що дозволяє включати або 
виключати фрагменти коду, які не підтримуються певною версією операuійної 
системи. 
Addressables [5] є плаrіном для Uпity, який дозволяє ефективно управляти 
ресурсами в мультиплеєрних іграх. Він дозволяє розробюшам зменшити розмір 
гри, прискорити час завантаження і покращити продуктивність за рахунок 
відокремлення ресурсів від коду гри. Addгessables [5] дозволяє здійснювати 
завантаження ассетів асинхронно, що дозволяє грі продовжувати свою роботу, 
поки ассети завантажуються. Крім того, він дозволяє використовувати різні 
варіації ресурсів для різних пристроїв, що дозволяє зменшити розмір гри та 
покращити продуктивність на різних пристроях. Addi-essables [5] також дозволяє 
розробню<ам з легкістю управляти ресурсами під час розробки гри та має 
вбудовані інструменти для перевірки стану ресурсів під час роботи гри. Однак, 
для використання Addressables [5] потрібно б.ільше часу та зусиль для 
налаштування його у грі, а також можуть виникати проблеми сумісності з 
іншими плагінами та інструментами розробки. 
Міпог [6] - це бібліотека для розробки мультиплеєрних ігор на Uлity [ l], 
яка дозволяє ефективно вирішувати проблему синхронізації гри :між rшієнтами 
та сервером . Mirror [6] забезпечує реалізацію мережевої архітектури заснованої 
на моделі клієнт-сервер. 
Mirror дозволяє зменшити навантаження на сервер, осюльки кшєнти 
можуть обробляти частину логі1<и гри. Бібліотека надає ряд вбудованих функцій 
12 
1l) (TY JJ І 1)2(> .01 І ПЗ 
ДJЩ • Р)''ІІІ()І '( ) ІІІІКОJ>ІІ<.:тш 1ш1, ТІ ІІОІХ SIIC JЮ'ІІЮJtіж: 11і uG' ' ІПІІ , (.;JIIIXf10JJi · 1:щi}І 'JМі ІІ 
· 1і111111х 111..-
• 11 • · 
LЩІ'ІІІ ІІОІІЩОІ\ІJ І І: 111, Т/1 Uillїl'J() і1111ю1 ·0. 
j\Іfі П(ІІ' 11і.1 11 ·р1ІІ\І\'(' НІ\" LJl)P / 17/ . ., . . , . ' ) . І . • • 
• • , 1.11, 1 / ( І І ІК/ 1 ( Jt11a1111,i. Кр,,.., пт.1, Мrпо,· 
11 ' (J 'J)ШI)'( ' /\J)()~IJ /f ' I П/юprщ:11 i • · · · 
· • L 11 •• нн.rу r.1шкс uутн 11111юр11сп111111ї ;uнr p<лpuG1<11 
l)'Jll,'11111.IILTf)IIJІ:'1: ЇІ\)f) ІШ UV) t І 
• J • І, -щшх шr.rп юрмах. тс і пі11тр11муют1. U11ity. Ою1ісю 'і 
Ul:tlUUIIIIX 11\..'Р~ІІІІІ ' Мі1тu1· ( ' " . 
ІІОІ O 11рщ:т()та 11111юр1н;та11т1 . Він ·mG~111u11yc ·1ру•111ніі 
ЛР1 щш JIO:J J)OUJШ /\J)'J/1 '1'111 1)  \ . . . . .. 
• Іt:< 1н111х 11 ор. mш11 ;10111ш~н1 · ро·,1юG11111са І\1 111111m1ю 
~ПЮf IOU:11'11 Іt:рt:ж~ві </,у111'· 11ії · І( . . ' 
І рІІ . рш 'J'()J '(), l\1J11тш· (' ІІ ІJІ/СfШПІ І\І ) {il<Cf1CJ/UM j мас 
l:)t'JII I К}' L'IJ іщ,1 юту 11 1() ) , , • G 
. , , 10"1юш1с ро:.11>0 11111юш отr11мат11 1111111лку та яюс11у 
11 1-р11м~у u 1x1:.s i 11отр~G11. 
Бібніоп.·к1 l\1Jі 1то І · [(>] , u 
<  , (JЩ 11·1 1)' ІІІІІ\()J1ІІС '/ '()/1)'(' Тt:Х ІІШІОП·Ї  ·, р,111(.;І JОрту, так і нк 
UDP•  ,l (JJH 1•·1 6t :': .І ІІt.:,  Іt'; ІІ ШІ ІІ : І ,'(1.1.1. 1/І)J l ) І іІ ,. . 
IIJIIJl,'{l,OI О UU;\ ІІІІУ ,'1 :t//1/Щ/ ;\ І і і" 
І01іппам11 та c~put:poм. Вона т.11ю;.1, 11111ш1mс rш1ус тсх1101югії серіап і ·J:щії ;ш11нх , 
,1кі як Vпity's JSON, дnя 11ерсд~Р1і uб 'сю ін міі" к11 і с111 а .\ІІІ та с~рв~ро.,1 . Mirror 
т~н-:ож ВШ'-"Орнстоnус механізмн с1111хро1 1і ·J:щії стш1у rp11, такі як Starc 
yпcf1ro11ization та Rcnюrc Proccd1m.· Calls ( l{P ') / 7 J, :t·iя ·1.iG~ ml'11c1111я 
ш1хроніз:щії даннх між кліснтамн та ссрuером. 
О гже. ро:1робка n галуз і ро'Jробю, ігор 1ш U11ity ·1 а сулуr11іх Тl'х110:юrій с 
\. Же важл11uнм, оскілью, це до·шш1яс внрішущп 11 111юu.1Іl' ;\ІІ J ~:фt:ю ншю1 u 
управління ресурсамн, nідn11щсн11я nропукпш,юсті т:1 ·3 абс:тсчс111 1я коре1,.ї1юї 
сннхронізаuії між клієнтами та сервером у му11ьт11ллс<.:рш1х іграх . Р~зу.1ьтuт11 
розробкн можуrь буrн корнсннмн дт1 і111ш1 х ро·~робшшіо і гор. які шукають 
способи для покращення якості с1юїх 11рОіtу1\гін та :.тбс:тс11с11ня бі:11,ш ·зручноru 
та ефеhтнвноrо лосоіду для кор11С1)'В.lt1ів . Кр і .,1 того, розробкн у ціП гз.1у1 і 
,,... <,,J • • • • • ,,,,,,, 
.,южуrь допомогти розрооннкам знш1п1 нов, р1шсш1я п1 техно:юr11 :L'ІЯ розроокн 
ігор, що в свою чергу може 110зитшз1ю uшшнутн на розшнок га;1уз 1 н 111 .1ю~1у. 
1.3 Огляд існую•н1х ана 1огів 
Однн з аналогів кооперативннх irop - Amonl:? U ·. Го ювна мета грн полягає 
в то.\fу, щоб знайти і видалити "зрадника " (одного або кількох) на космічно.чу 
ЧДТУ 231926.01 І ПЗ 
>раблі, який повинен виконувати завдання та ремонтувати пошкодження . 
равці ~ІО!hуть брати участь у грі через Інтернет або ло1<альну мережу. 
Для розробки гри використовується Unity. Весь код написаний на мові С#. 
нтерфейс користувача розроблений з використанням компонентів Unity, таких 
:.к кнопки, текстові поля і т.д. Головна логіка гри зосереджена в скриптах, які 
~ерують рухом персонажів, завданнями, анімаціями та іншими аспектами. 
Одна з головних складових гри - це мережевий код, який забезпечує 
~в'язок між гравцями під час гри. Для цього використовується стандартний 
Unity Net\-Yorking APl, який дозволяє створювати мережеВІ додат.ки та 
обмінюватися повідомленнями м1ж ними. Крім того, в грі використовуються 
засоби забезпечення безпеки, такі як шифрування повідомлень між 1шієнтами та 
сервером. 
В цілому, код гри Among Us [8] виявляється складним і детальним, з 
багатьма взаємодіючими скриптами та компонентам:и, які відповідають за різні 
аспекти гри. Важливо звернути увагу на мережевий аспект гри, оскільки він 
відіграє ключову роль в забезпеченні взаємодії між гравцями під час гри. Для 
забезпечення цієї функціональності гра використовує баrатокористуваць1<у 
мережу, засновану на протоколі UDP, та бібліотеку LiteNetLib. 
1.4 Конкретизація завдань роботи 
Основна ідея роботи полягає в розробці мобільної гри на Unity яка буде 
дозволяти грати разом кільком людям без доступу до глобальної мережі 
інтернет, використовуючи функцію "Портативна точка доступу Wi-Fi", або 
підключення до іншої спільної лоr<альної мережі. В результаті роботи було 
виконано основний план та завдання, а саме: 
Створено мобільний додаток. 
Реалізована можливість гри по локальної мережі без доступу до інтернету. 
Створено геймплей, який буде поглиблювати гравців в гру. 
14 
ЧДТУ 231926.011 ПЗ 
РОЗДІЛ 2 
ПРОЕКТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ СИСТЕМИ 
2.1 Моделювання предметної області 
2.1.1 Предметна область моделювання. Модель предметної області . 
::::ловниr< предметної області 
Кооперативні ігри - це вид відеоіrор, в яких гравці спільно працюють для 
досягнення спільної мети. У та1сих іграх гравці зазвичай виконують різні ролі та 
завдання, які доповнюють один одного та сприяють досягненню спільної мети. 
Однією з ключових рис rсооперативних ігор є необхідність співпраці та 
комунікації м1ж гравцями. Гравці повиню обмінюватися інформацією, 
планувати своІ дії та координувати їх, щоб досягти спільної мети. 
Головним елементом є геймплей, який має ключову роль в розробці гри. 
Геймплей повинен відповідати жанру гри і бути комфортним для гравців. 
Гравці можуть створювати лобі та приєднуватися до інших лобі. Вони 
та~юж можуть створювати та зберігати ігрового персонажа, керувати ним і 
взаємодіяти з ігровим інтерфейсом. 
Лобі гравців може приймати гравців, перевіряти готовність гравців до гри 
та запускати сцену 1грового процесу. 
Ігрові персонажі можуть атакувати ворогів, перем1щуватися по сцені та 
взаємодіяти з різними предметами та зберігати їх. 
Сцена може містити гравц1в та ворогш, створювати персонажів, 
відображати ігрові декорації та об'є1сrи та мати рівень, який збільшується. 
Рівень може надавати інформацію сцені про ворогів, яких потрібно створити. 
Вороги можуть атакувати персонажів гравців, переміщуватися по сцені та 
створювати предмети після своєї смерті. 
Предмети можуть зберігатися в персонажах, лежати на сцені та випадати з 
воропв. 
Графічний інтерфейс може відображати інформацію про персонажа 
гравця та інформацію про сцену та рівень. 
Словник предметної області : 
15 
ЧДТУ 231926.011 ПЗ 
1 Геймплей - основна частина гри, яка включає в себе механ1ки та 
авила гри. 
2 Жанр гри - катеrор1я, до якої належить гра залежно DІД її 
обливостей та стилю геймплею. 
З Гравець - особа, яка грає в гру та взаємодіє з ігровим інтерфейсом. 
4 Лобі - віртуальний простір, де гравці можуть приєднатися до гри, 
:ворити гру та взаємодіяти з іншими гравцями. 
5 Ігровий персонаж - віртуальний об'єкт, який гравець може керувати 
:1 взаємодіяти з іншими об'єктами в грі. 
б Взаємодія - можливість об'єктів взаємод1яти м1ж собою, зокрема, 
равців з персонажами, персонажів з предметами, тощо. 
7 Сцена - віртуальний простір, де відбувається ігровий процес, 
,1істить об'єкти, декорації та інші елементи гри. 
8 Рівень - певний етап гри, на яко:му гравці повинні виконати певні 
~авдання або дійти до кінцевої мети. 
9 Ворог - віртуальний персонаж, яrшй протистоїть гравцям та 
намагається завадити їм у досягненні мети гри. 
1О  Предмет - віртуальний об'єкт, який може бути зібраний гравцем або 
використаний для досягнення мети гри . 
11 Графічний інтерфейс - віртуальний інтерфейс, який відображає 
інформацію про гру, зокрема, про гравця, сцену, рівень та інші елементи гри. 
2.1 .2 Елементи моделювання предметної області 
Програмне забезпечення кооперативного мобільного Jгрового додатку 
буде розроблене на основі Unity, це двигун який використовує об' єктно 
орієнтовану мову програмування С#. Саме тому при побудові елементів 
моделювання предметної області будуть використані діаграми мови UМL. 
При проектуванні роботи будуть використані основні діаграми UML [9]. 
За допомогою них буде створено основне моделювання предметної області, 
загальна структура буде мати наступний вигляд: 
16 
Д\,\\'\Ш\\11 
"~·н, ... ,,, 
.'\.\~,,,. . " .. 
~ 111~·~\)'\Щ 
\-\ )\\"' І"'"" 
І\\\~,• 1·\\\ 
Д\1>111:0:-.t>\ 
\\(\\\\'.,"1.\11"11 
Рнс. 2.1 - Загальна струю·ура U1v1L діnграІ'\•1 
2.1.3 Робоча область :моделювання 
Лобі зберігає список гравців, перевіряє їх стан та запускає ігрову сцену, 
якщо всі гравці готові. 
Основний геймплей та взаємощя грш:щш відбувається на сцені. Сцена 
складається із набору ігрових персонажів та ворожих персонажів, та поточного 
ршня. 
Ігрові персонажі r-.южуть атакувати ворожих персонажів, пересуватися на 
сцені та підбирати ігрові предt-.1ети. l'Лають певну 1<ількість здоров'я, набір 
предметш. 
Гравець може керувати ігровим персонажем. Він :має своє і·м' я, та елемент 
інтерфейсу на якш.,rу відображається інфорN~ація про персонажа та сцену. 
Ворожі персонажі керуються штучним інтелектом. Зберігають ігрового 
персонажа гравця та намагаються атакувати його . Мають набір здоров'я та 
предмети які випадають коли рівень їхнього здоров' я падає нижче нуля. 
Елемент інтерфейсу зберігає ігрового персонажа гравця та сцену, щоб 
відображати їх стани в вигляді інтерфейсних об'єктів, таких як індикатори. 
КНОПКИ l ТД. 
17 
ЧДТУ 231 926.0 11 ПЗ 
Предмети мають назву, значок. та список властивостей які зм і нююп,ся У 
п ерсо1-~ажів. 
На рисунку 2.5 наведена модель основних сутностей системи . Ці сутності 
мають тісну взаємодію між собою та створюють основний rеймплей гри . 
Лобі 
Гравець 
Сцена Рівень 
Ігровим персонаж Ворожий персонаж 
Предмет 
Рис. 2.2 Модель предметної області програмного забезпечення кооперативної 
гри 
2.2 Формування та аналіз вимог 
2.2.1 Формування вимог до програмного забезпечення 
2.2.1 .1 Первинні і детальні вимоги 
ПЕРВИННІ ВИМОГИ: 
Гравець повинен мати змогу зайти в гру та приєднатися до інших 
гравцш. 
2 Гравець повинен мати можливість вибрати персонажа. 
З Гравець повинен мати можливість керувати ігровим персонажем: 
переміщення, атаки, взаємодія з предметами. 
4 Ворожі персонажі повинні атакувати гравців та заважати їм. 
18 
1/J('I У ?1 I 1) :U1,О І І ІП 
~ '"'І"". 1у ,, 1 1 1і 11111 1 111111 і (1111111111 11н/юрм:111ію 11ро t:1ю1 о 11сrн.:011ажа ІІа 
· I,р1111I . 
І . І І 'р : 111~ 1(1, 1/(1111111~11 1\111'1 11 f, J (li/(JIII/I Ї (;T/, оuр:.пи UJ0-111 ,-~ ваrію1тін: 
11iJ t l\'J ІIO'IIITlll' )I /(О ЇІІІІІ()І 'О JІo fii :1 )() СТІІОрІП'Н 1/ОІІС ;юбі , 
І . ~ І 'р:ІІІ~ІtІ , 11 JюСіі ІІОІІІ'ІІІ t: 11 ма'І И МОЖJІИВісТІ> иийти З НJ,ОГО В будь-ЯІ<ИЙ 
І\ІОІ\І~ІІТ 1 Щl')', 
I .J І Іо1 11111ап1 І 'РУ м0>1с1..: тіт, 101 1 ·равс1t1, створиuший набі , а тако:;к тільки 
11і~ю1 ТОІХ) >ІІ< всі і11111і учасшши ;юGі 6у)(ут1) 1 ·отові. 
2. 1 Граuсц1, може 11срсі-іти в стан 1 ·ото1.ші-І. 
3. І І1.ювсц1, 110оинс11 мати змогу переміщувати irponoro персонажа. 
3.2 /1·1юuий 11ерсо11аж 1·-раиц.я 11ови11е11 мати змо1'у атакувати ворожих 
п~рсонnжіо. 
З.З Керуuання персонажа відбувається trepeз кнопки на дисплеї гравця. 
4.1 Ворожі персонажі повинні знаходити ігрових персонажів гравців. 
4.2 Ворожі персонажі повю-ші атакувати ігрових персонажів гравuів 
я1<що вони будуть n радіусі їх сприйняття. 
5. J Рівень повинен створювати ворогів раз в кілька секунд. 
6.1 На екрані повинна бути інформація про ігрового персонажа: його 
рівень здоров 'я, рівень енергії. 
2.2.1.2 Вимоги замовника розробника. Функціональні та 
нефункціональні вимоги 
Зазвичай, розрізняють дві категорїї вимог. Первиннj, що називають 
вимогами замовника та детальні, що є вимогами розробника. 
Первинні вимоги фіксують побажання та потреби замовника, тому вони 
викладаються мовою, зрозумілою для нього. Збір або формування вимог - це 
етап роботи з первинними вимогами . Детальні вимоги описуються в 
спеціальній структурованій формі, що їх деталізує відносно первинних вимог. 
Тому вимоги замовника і розробника стосовно цієї роботи були описані в 
попередньому пункт~. 
19 
ЧДТУ 231926.011 ПЗ 
Функціональні вимоги: 
1 Гравець повинен мати можливість зайти в гру. 
2 Система повинна дозволяти гравцеві створювати нові ігрові лобі та 
приєднуватися до існуючих. 
З Гравець повинен мати можливість переглядати список доступних 
Ігрових персонажів та обирати одного для гри. 
4 Гравець повинен мати можливість перем1щатися по сцею гри та 
атакувати ворожих персонажів. 
5 Ворожі персонажі повинні мати різні характеристики (напраклад; 
швидкість, здоров'я, рівень атаки) та поводитися різним чином залежно від цих 
характеристик. 
6 Система повинна зберігати статистику гравцш (кількість 
знешкоджених ворогів) та відображати її на екрані користувача. 
Нефункціональні вимоги: 
І Ефективність: гра повинна бути достатньо ефективною, щоб 
запобігти затримкам та зависанням. 
2 Надійність: гра повинна бути надійною і не має падінь під час гри. 
З Безпека: гра повинна бути безпечною для користувачів. 
4 Придатність до використання: інтерфейс гри повинен бути простим 
у використаню, штуїтивно зрозумілим та легким у навігації. 
5 Сумісність: гра повинна бути сумісна з р1зними платформами, 
наприклад, мобільними пристроями і комп'ютераr-.ш. 
6 Розширюваність: гра повинна бути розширюваною, щоб додавати 
новий контент, наприклад, нові рівні, ігрові персонажі та предмети. 
2.2.2 Формування вимог за допомогою діаграми прецедентів 
Діаграми прецедентів будуть зроблені на основі мови UML. В таких 
діаграмах позначається <<actor>> який може бути представлений у двох 
варіантах. У формі "чоловічка" та запропонованоі" розробником піктограми, рис. 
2.3 [9] 
20 
ЧДТУ 231926.011 ПЗ 
Q 
л 
Cnlopo6 Ітннк 
Рис. 2.3 - Варіанти графічного позначення актора: 
а - у вигляді «чоловічка»; 
В роботі існує чотири види акторів: 
І Користувач - той хто тільки запустив гру. 
2 Гравець, це користувач який знаходиться в лобі перед початком гри. 
3 Ігровий персонаж, це персонаж який керується гравцем під час гри. 
4 Інші гравці - користувачі які вже приєдналися до лоббі. 
Після визначення списку акторів, йде визначення списку варіантів 
використання. 
Варіант використання це взаємодІЯ актора та системи. На основ~ групи 
вар~анпв використання у системи визначається її поведінка. Кожен варіант 
використання належить одному із акторів. 
Система лобі 
Рис 2.4 - Діаграма прецедентів лобі 
21 
ЧДТУ 231926.Ul І 11~ 
--------------- ----- ----· - - І 
Система -
керування І 
І 
, , , ,• . 
,• >•t,,,clude• > 
. --, _-., .,,,,tudc:.,.,."• •, ' ... 
«JІІСІUОе» / 
е'оро 11·, nерсонаж ДDІt, 
Рис. 2.5 - Діаграма преuедентів 1<ерування 
Система 
rеймплею 
Рис. 2.6 - Діаграма преuедентів гей ,шлею 
22 
ЧДТУ 23 1926.0 І І ПЗ 
2.3 Прое1,1·ушшш1 JІОІ'ЇЧНОЇ СТf}УКІ)'J)ІІ ЩНН'(ШІ\11101 '() І~ОІ\ІІІ./ІСІ~С)' 
2.3.1 Діаграми 1<ласів 
« l.!oundary» 
Ch.1ractersl lstView 
- characters[1• . "] 
• AddCharacter(Character) \'Old 
• ReinoveCharaclEЩCharacter) vord 
• GetCharacterщnпg паrпе 1 · Character 
о 
н ◄ • н 
«control» <<COl1tr'OI» «со1111 0І>> 
ChJГJc\orCreat1011 СІ1ОІ'іІС\О І"0ОІо\о Clшoctu1·Soluc t1011 
• CreatetCl1srac1er}. vold • Delote(Cl1or-1clor): vold + Sulocl\CІ1мoctu1 1. vultl 
~-. І]\ ."l 
' 
U$o U's c , U;o 
', ' 
' , • 
' • ' 
«1111 \lty» 
Ctщr~ctor 
- 11an1e slring 
- І1еаІІІ1: noat 
- Іevet: ІпІ 
• GetNarнe(): ~,r1no 
+ Getleveю· Іnt 
+ GetHeallh(): f1oal 
• SetNanle(strrng): voltl 
" SetLevet(Іnt): vold 
• SelHeallll(lloal): vold 
Рис. 2.7 - Діаграма класів сценарію стnорення, видалення, вибору персонажа 
«entity» «er\li ty» «Co111rof)> 
Character LоЬЬуРІауе г LobtJy 
- name: strlng • lsReady: ЬооІ - ptayers[1 .. 'І: LobbyPІ~yor 
- health: noat о + ІsLоЬЬУОІ'ІПеr: ЬооІ 
- Іе•,е І: int + PlayerCharacler: СІшзсtеr <> 
• GetNameo: strlng н • S1aГ1Game(): YOld 
• Getl~Yel(): 1nt • дddPloyer(Connectlon) . vold 
• GetHealih(): fioat • Ren1ovePlsyer(Connec1101). vold 
• SetN;;me(stm9): vold -AIIPІayersRoady() : ЬооІ 
" SetLevel(int): void 
" Setнeallh[flo at) : VOld ,-::J 
,, 
,, 
, 
!,)se 
«boundary» , 
LobbyPloyerView 
- name: техІFІеІd 
- is01vner: TextField 
• ІsReady: Te~iF1eld 
• SetReady(Character): void 
~ StarIOame(Chaгacter): void 
+ RpcUpdaieVie1•1(strin9, ЬооІ, ЬооІ) VOІd 
Рис. 2.8 - Діаграма класів сценарію початку гри 
23 
ЧДТУ 231926_011 ПЗ 
«CoI1trol>> <<Control>> <<Control>> 
Lobby 
SceneLQ.Іder NetworkM.111.iger 
- sceneName· stnng - sceneLoader. sceneLoader - playersІ 1. . Т LobbyPІay9r 
..~_ .. ~ 
~ 
• LoadSc.eГІe[). VO!~ 
• StartClicnl()' vold • St;;rtGame(). vord 
- Staг.Hosl() voкJ • AddPІayer(ConnecнonJ. vo:d 
... RemovePІayer(Connect1on) · 
void 
-AIIPІa1·ersReady()· ьооІ 
() 
(J 
«еI11I1у» 
«l>OUІHJdry» LobbyPlayer 
LobbyMen11 
... ІsReady: ьооІ 
- nIckName: Teл1Frcld • ISLObbyOV,11er: ьооІ 
• PlayerCharacler. Character 
+ Connec(O: void 
- Createo: void 
Рис. 2.9 - Діаграма класів сценарію підr<лючення до гри 
«boundary>> 
CІ1arncterC011trol 
" Up(!atel): VOІd 
<<control:>> <<control>> 
CharacterC0111bat 
<<control>> Ch.iracterPrckup 
CharacterМoveinent + Attack(Cnaracter~ vold • Plckup(Іtem): vold 
т BІocJ,:(Character)· void 
+ Move(Vector2 direction): void • Drop(lt~n1): void 
«e11tity» 
Character 
«entity» 
+ Name: string ltem 
+ неаІ!h : ПоаІ 
"Level: int І',,,,-- -----1 "'Nsme: slrin9 
• Veloclt)': Vactor2 <(--------Us~----- ----- .. tc.on: ісоп 
• ltems: Hem{1 ..• ] r--------- ------i 
• OnEQuip(Character): void 
• Update(): void 
Рис. 2.1О  - Діаграма класів сценарію пересування персонажа, атаки та підбору 
предмету 
24 
ЧДТУ 231926.011 ПЗ 
c:c:control>;:, 
TargetFinder 
c:c:entity>> + F1nd(): Characler 
Enemy 
+ Taroet: Character ~ -
1--
+ наsтагgеІ(}: ьоо І - с:с:со 1шо1» 
EnemyMovemeпt 
+ Move(Character destination): void 
Extends 
t 
c:c:eпtity>> 
c:c:coпtrol>> 
Character Charactercombat 
.,. Name: string 
+ Health: float ,... + Attack(Character): void 
+ Level: int ._. + Block(Character): void 
+ Velocity: Vector2 
+ Іtems: ІІеm 
+ UpdaleO: •1oid 
Рис . 2.11 - Діаграма класів сценарію атаки гравців ворожими персонажами 
«entity>> 
«boundary» Level 
LevelHud <<entity>> 
.... + Difticui!'f. 1nt .... LeveІCondiUon 
• currenlDifficult'J: TextFleld .... + Spa1·mer. CharacterSp.1·1ner ... 
• CheckO: ЬосІ 
+ UpdзteVieІ\t): void 
+ Spa1·,тiEr.em'((): void 
+ lncrшeDiffitu!ty(). void 
j ) 
«entity» 
«еnШу» .... Character 
CharacterSpavmer ... 
+ Name; slring 
+ Spa1·1ncd: Charatl~rj] • Heallh: fioat 
+ Level: inl 
+ Spa;•1nQnl d1fficutty} ЬооІ + Velotity: Vector2 
+ Іtems: ttem 
+ UpdзteO: vold 
Рис. 2.12 - Діаграма класів сuенарію системи геймплею 
25 
ЧДТУ ~31926.0 1 І П З 
2.3.2 Діаграм 11 1 шкt: гі в 
І 
Б1блютск..~ 
ІнrерфQйс11их сщ,щщrю -. 
u,111yE11u111 11J .:H M()J\11 
. UІ 
,.111 ,о, 
_ j ___т  ___  
111нІІі1 оо ·н. r 11 
AtlVІJ lllur,•r tjo111, O\Jjrr І-. 
>1щ,о 
Ac.J v1:111urtн Coru 
Сс:µНІL М 
A<Jv n1111er є rv1ce ~ 
Рtн:. 2 . 13 - ,'!1шра.\Іа 11аt-с..'ІІІІ ІІ(І(.І L'ІІс.."І~!ІШ 
2.4 Apxi·rckї")'pнr 11рое"1 уш111ш1 
~ -➔ . І Діагра.-.,~ 1ю.-.ню11r111 ів 
< <.<.Ott,p(,t, fnt> > 
La,t,y/1 'IU --,І  
Г1 
;...__ -;'-.'., 
Рис . 2. J4  - Діагр.1,1а ко,111 Нl'НТІН ,ючатку грн 
ЧДТУ 231926.011 ПЗ 
RPC 
r · •. ·, 
І 
І <<со111роnе1н» 
І 
І Gan1eptayNetwork State 
І 
І 
І 
"'-<component>)c5l «componen\>)· с51 
Sc2neloader ~ NetvюrkManager ~ 
«componenl>~ -~-~component>;:c5l 
Ne~.volkBehavio~ Character ~ 
І 
І <<con1ponen\>~ -~<componeni>)c5l 
І 
І 
І Leve\ ~ Ne!VІOГkS\a\e ~ 
І 
І 
І 
І 
І 
І 
'· ... ·' 
Рис. 2.15 - Діаграма компонентів гемплею 
Messages 
r ....,  
І І <<conipo11ent>> 
; І 
Unity Remote Procedure Calls 
<<con1ponent>>c5l 
NetvvorkSerter ~ 
<<coniponent;:-;:91 
Net\11orkBehaviOtfi2.J 
« componen\>)c5l 
Nei1NorkC!ienl ~ 
І 
І 
І 
І 
І 
І 
І 
І 
І 
'- .. - - ..1  
Рис. 2.16 - Діаграма компонентів роботи RPC повідомлень 
27 
ЧДТУ 23 1926.011 ПЗ 
2.4.2 Розгортання програмно"і системи на апаратних засобах. Діаграма 
розгортання 
І І 
НоєіСІіеn! 
<<coшponent::-::~ 
Ne~vorkClien! 
~ 
• І, 
<<coтponen!>:=~ 
NetvюrkServer 
/1 ~ J 
1' 
І І І J І І 
Clien! СІіепІ Client 
<~~~;:г~~~~~)~ <<co11їponen!:=·:=~ 
Ne~NorkClient <~~~~lг~~І:~і~ 
) l/ І 
Рис. 2. 17 - Діаграма розгортання 
28 
Ч/J,ТУ 23 1926.0 І І ПЗ 
2.5 М(ЩСJІЮШШШІ шннщішш CJf CT<:M.И 
2.5. J )0'1r ·puмu J(іШІІ)І/ОСТі 
Вибір персонажа 
Персонаwjв 
немає 
Створення новоrо ПошуІ( існуючих 
персонажа nepcoнawJв 
Поv.азати списо к 
персонаЖЇв 
Вибір персонажа зі 
С Г.ИС!(У 
Рис. 2. J 8 - Діаграма діяльності для створення персонажа 
29 
ЧДТУ 23 І 926.011 ПЗ 
Запус;~ гри 
Перев ірка ГОТОВНО·СТЇ 
зсіх гравців 
Усі гравці 
готозі 
Запусїити сцену 
rеймплею 
Рис. 2.19 - Діаграма діяльності для запуску гри 
зо 
ЧДТУ 231926.011 ПЗ 
Натискання на 
,:нопку Тотовий" 
Перевірка 
можливості бути 
готови,., 
Гравець 
задовільняє 
вимогам 
готовності 
з,.,інити стан грав ЦF, Змінити стан гравця 
на "Готов11й" на "Не готовийu 
Рис. 2.20 - Діаграма діяльності для зміни стану гравця 
31 
ЧДТУ 231926.011 ПЗ 
Пошу1:лобі 
Лобі 
~з_н,а;;і;.;с:::щ:е.:.: ..:.-но=--~ По1:азати знаі,дене ,___ _ .., П(ДКЛЮЧІІТІІС:, ДО 
Лс:=і і обраного лобі 
СТ:орип1 ноае лобі 
Рис. 2.21 - Діаграма діяльності для nідключення до лобі 
2.5.2 Діаграма послідовності 
Scen~Loader Ne~;;orl<Man,ger LobbyMenu 
Lobb~Player ' 
''І  
''  ' 
,.';.  ' 
LoadSceneo '' '  ..:. 
SІartClienl() 
relu,n 
< ······ ··· ··· ······ Synclobby() ..:. 
,.''. .
  
' Sho,·1Lobbylnfo() 
''  
'' І • 
~-----· ............... --.. .. .. ::  ·--------------- rolurn
..... ------ -L.o..b..b..y -P-la·-yers 
... .. --..... ~ -- .. ------~: -- . -· -------. ---........ --.. 
'' о  .'  '' І  
.''  '  ''
'  
'  
Рис. 2.22 - Діаграма послідовності сценарію підключення до лобі 
32 
ЧДТУ 231926.011 ПЗ 
CreateCharactєr DeleteCІ1aracter Selt?ctCharacter 
CreateO 
Update() 
Update() 
DeleteO 
' 
..,_ : reІUm Ch3r3ct~rs : 
-._- • -•••-•--••--•••---~••••••••• ••••••••• • •••• • ••:• •••••••••••••-•••••••••-- - -L-- -•••••• • •••••• • •••• • • 
' 
Select() 
' '' '  
: retum Ch3racter : 
<-------------------·-------------------------.,'- --------- -----------------
' 
Рис. 2.23 - Діаграма послідовності сценарію створення, видалення , вибору 
персонажа 
2.5 .З Діаграма комуні1<ації 
Sccncloaoe, 
+ LoadScene() ~----~ ~•~tC
~ ,.'l_l~~r"- (-)- ---, 
А Nel\vorІ<Manager 
LоЬЬуРІзуеr 
Sho1·1Lobbylnfo() ~ 
.___L_оь_ьv_м_е_п_u  _. +- - --- L...::_j 
Рис. 2.24 - Діаграма 1<омуні1<ації сценарію підключення до лобі 
33 
ЧДТУ 231926.01.1 ПЗ 
:5:: C,oat,() 
CreateCharacter 
LobbyPlayer 
Cl1aractersListVie1лr 
Select() DeleteCІ1aracter 
Se1ectCІ1aracter 
Рис. 2.25 - Діаграма комуні1<ації сценарію вибору персонажа 
2.5.4 Діаграма скінченного автомату 
Leave 
ІоЬЬу 
MainMenu GameplayState 
entry/Start net•.vork entry/tnit players 
doІSelect І оьь,, 
t------+І exitJSet connect type 1------ dolSelect character 1------ do/Run ІеvеІ 
exit/Start gameplay exitJFinish ІеvеІ 
Exit from 
oarne 
• 
Рис. 2.26 - Діаграма скінченного автомату ігрового процесу 
ldleState PalroІSlale AtiackState 
І---~ entry/Stay 1------+1 do/Fi11ding рІєуеr 1-----~ do/Atlзck рtзуег t-----• 
Рис. 2.27 - Діаграма скінченного автомату поведінrш ворожих персонажів 
34 
ЧДТУ 231926.01.1 ПЗ 
РОЗДІЛ З 
РОЗРОБКА ТА ТЕСТУВАННЯ ПРОГРАМНОГО ЗАБЕЗПЕЧЕННЯ 
З.І Розроб1са програмного 1сомnлс1ссу 
3 .1.1 Обrрунтування вибору засобів реалізації 
Для написання роботи на тему "Програмне забезпечення І<ооперативного 
ігрового мобільного додатr<у на основ~ Unity" використовувались таю 
технології, ЯІ< Uпity [І], Visнal Sn1dio [10], Мі1тог [6], DI контейнер [11]. 
Unity [ 1] - це один з найбільш популярних та потужних інструментів для 
розробки ігор, що дозволяє створювати високояr<:існі ігрові досвіди для різних 
платформ, включаючи мобільні. Використання Unity дозволя:є зосередитися на 
створенні гри, не витрачаючи час на розробку власного ігрового движка та 
інших jгрових ресурсів . 
Міпо1· [6] є бібліотекою для розробr<и мережевих ігор на Unity, яка надає 
дуже потужні та зручні інструменти для створення мережевих додатІ<:ів з 
мш1мальною кількістю зусиль. 
Один з основних принципів Ivliпo1· - це зменшення навантаження на 
мережу та клієнти. Для цього Міп-оr використовує принцип авторитетного 
клієнта, коли 1шієнт відправляє запити серверу лише на ті дії, яю вш здійснює. 
Це дозволяє зменшити навантаження на мережу, зменшити кількість лагів та 
покращити загальну продуктивність мережевої гри. 
Міпоr також дозволяє створювати мережеві додат1<И за допомогою однієї 
кодової бази для всіх платформ, що підтримує Uпity, включаючи мобільні 
пристрої. Це робить Міпог ідеальним 1нструментом для розробки 
кооперативних мобільних ігор на U11ity. 
Крім того, Мі~тог має потужну систему синхронізації стану гри м1ж 
сервером та клієнтами, яка дозволяє гарантувати, що всі гравці бачать 
однаковий стан гри в реальному часі. Це особливо важливо для мобільних ігор, 
де зв'язок з мережею може бути нестабільним. 
Узагальнюючи, використання Miri-OI для написання кооперативної гри на 
Unity дозволяє зменшити навантаження на мережу, забезпечити потужну 
35 
ЧДТУ 231926.О 11 ПЗ 
снстсму с1шхроні:Jації стану 
гри п1 зробити розробку мережевої гри більш 
зручною та ~фекпшною. 
Visш1I SІшІіо [ І О] є о;щією ::J найбільш потужних та популярних 
інтегроnаних розробних середовищ (IDE) для розробки програмного 
забезпечення ш· 1•  р1· зних моnах програмування, включаючи С# - мову 
програмування, я1<у шшорнстовує Uпity. 
Vist1al Stt1dio має безліч корисних інструментів та функцій, що 
допомагають роз ро б НИ.І <ам ш·д  час написш-шя rсоду. Н· а· приклад, шд· rсаз1ш коду, 
автодопоnненнл, вбудоване відлагодженнл та підтримка версійного контролю. 
Всі ці інструменти дозволяють зменшити кіль1сість помилок та зробити процес 
розробки більш ефе,стивним. 
VisLJal Stt1dio також інтегрується з Unity, що дозволяє здійснювати 
розробrсу та відлагодження коду безпосередньо в середовищі Unity. Це дозволяє 
відразу баtrити результати змін в коді та швидссо реагувати на помиш<и. 
Крім того, Visual Sn.1dio має потужну систему плагінів, яка дозволяє 
розширювати можливості IDE та налаштовувати її для власних потреб. 
Наприклад, плагін Resl1шpeг [ 15] дозволяє збільшити продуктивність розробки, 
зменшити кількість помилок та збільшити якість коду. 
Узагальнюючи, використання Visual Studio для написання кооперативної 
гри на Unity дозволяє зменшити кількість помилок та зробити процес розробки 
більш ефективним завдяки потужним інструментам та функціям IDE. Також 
інтеграція з U11ity дозволяє швидко вjдлагоджувати код та бачити результати 
змін в коді безпосередньо в середовищі гри. 
DI contaiпe1· (Dependency Injectioп [ 11] containeг) є корисною технологією, 
яка допомагає розробникам униrшути юлькох недошюв, пов'язаних з 
безпосереднім створенням об'єктів та залежностей між ними в коді. 
Один з головних недолі1<ів, пов'язаних з безпосереднім створенням 
об'єктів та залежностей між ними в коді, полягає в тому, що код стає менш 
зрозумшим та с1<Ладним для розум1ння, що знижує його яюсть та 
розширюваність. 
36 
ЧДТУ 231926.01.1 ПЗ 
DI containeг доnоJ\1••, ,гає розро 6 никам зберегти розширюваюсть та 
зрозуl\Іілість коду, надаючи можливість залежностей та їх налаштування в інших 
і\Іt~цях програми . DI coпtainer приймає на себе nідповідальність за створення та 
налаштування об'єІСтів та їх залежностей, що дозволяє розробнию:\М 
:зосередитися на основній логіці програми. 
Kpil\-t того, DI containe1· допомагає зменшити кількість коду та покращити 
ІІОГО перевикористовування, оскільки дозволяє розробникам відокремити 
створення та налаштування об'єктів від основної логіки програми. 
У контексті кооперативної гри на Unity, використання DI сопtаіnег може 
6уги корисним для налаштування та створення залежностей між компонентами 
гри~ такими як 1<0нтролери, .r,.,rенеджери, або різні ігрові об'єкти. Наприклад, DI 
containeг може допомогти створити залежність між гравцями та ігровим 
сервером, що забезпечує здійснення обміну даними між ними. 
Отже, використання DI contaiпer є r<орисною технологією для написання 
кооперативної гри на Unity, оскільrш дозволяє зберегти розширюваність та 
зрозумш1сть коду, зменшити юльюсть коду та поr<ращити його 
перевикористовування. Крім того, DI со11tаіпе1· допомагає знизити залежність 
між компонентами гри та робить код більш модульним, що полегшує розробку 
та шдтримку. 
Наприклад, якщо в rpi є декjлька видів зброї, то залежно вjд типу зброї 
гравцю можуть потрібні різні сервіси. Використання DI containe1· дозволяє легко 
налаштувати залежності між гравцем та сервісами в залежності від його типу 
зброї. Крім того, DI contajпer допомагає забезпечити тестовання окремих 
компонентів гри, що покращує якість гри та зменшує І<ількість помилок. 
У залежності від конкретних потреб та завдань, DI сопtаіnег може бути 
дуже корисним інструментом для розробки кооперативної гри на Unity. 
Використання .DI соntаіпег спрощує розробку та підтримку гри, забезпечуючи 
зрозумілий та розширюваний код. 
37 
ЧДТУ 231926.011 ПЗ 
3.1.2 Опнс струh.·турної (функціональної) схеми 
Unity викор11стовує підхід СОР [ 12] (Coшpoпeпt-Orie11ted Pгogra111111i11g), 
;кількн він дозволяє створювати більш гнучкі та повторно виr<аристовуванj 
)Мпоненти, що можуть бути додані до бущ~-якого об'єкту в грі. 
Компоненти - це самостійні модулі~ які містять поведінку та/або 
1астивості об'єкту. За допомогою компонентів можна легко додавати нові 
fНКдії та властивості до об'єктів без необхідності розробляти новий клас для 
,жного нового елементу. 
Крім того, підхід СОР дозволяє лепю створювати ієрархію об'єктів, що 
1ють різні властивості та поведінку. Це можливо завдяки тпму, що компоненти 
>жуть бути додані до будь-якого об'єкту в ієрархії. 
Також СОР дозволяє зменшити залежність між класами, що зменшує 
ладність розробки та підтримки коду. [16] 
На рис. З .1 зображено структурну схему вс1х мережевих компонентш 
стеми. Кожен мережевий компонент успадковує NetworkВehavioнг [6 ], який є 
стинаю бібліотеки Міп01·. 
Компонент успадкований вщ NetwoгkBel1avioнг [6 ] може користуватись 
режевими функціями, такими як: RPC, Data sync. 
.r· --------------- --- --- --,:  r· -- ------------------- ·-: 
: OTHER : 
CLIENT : CLIENTS 
' І І 
І 
Інтерфейс 
''  .'  ' 
''  
користувача ''  І ' 
:' 
І 'І  
 : І 
І 
l ' ' ' :' 
І'  '  
' ' '  ''  І І
' І 'І  
І rроа11й ко1.1понент ' І 
Іrрозий компонент 'І ' 'І  І rроsніі компонент 
І 
''  'І І '' І 
І 
І'  ''  І'  І 
~ ' ' ' І 
''  ' І 
І ' ' і 
І ' І
''
'  І : І 
'  ' 
Бібліоте1:а Mirror ' Бібліотека Mirror ' 
Бібл іопн:а Mir.-or 
І 
''  ' ''  
І ' 
І ' : : 
І 
l ''  'І І 
І 'І  
'' 
І 
'  .'І  І 
І І 
І r 
' RPC '  ' RPC ''І  
''
І 'І І 
І  І 
І 
І • 
Nel\'I0ГkBehavl0~IГ . Nel\·10rk:B'el1 aviour І • 
' Netv1or1<6eha\•ioш 
І 
І ' -
І'  ''  ' 
''  І ' 'І 
' ' ' 
' ''  о І 
І І І 
' ------------------- --- --J ·----------------- ------- · ~---------- -- ------------' 
Рис. з .1 - Стру1<турна схема мережевої взаємодії компонентів 
38 
ЧДТУ 231926.011 ПЗ 
На рис. 3.2 показана струюурна схема лобі. Вона включає в себе таю 
підсистеми: 
1 Створення персонажу - система яка відповідає за створення нових/вибір 
існуючих персонажів. Вона зберігає та завантажує персонажів із бази 
даних. 
2 Підключення до лобі - система яка взаємод1є з мережею та оперує 
вхідними запитами. Вона також перевіряє готовність усіх гравців до 
початку гри. 
с~1стема Lobby 
Підсистема 
створення Підсистема 
ПЄРСОНа)ї..'У підключення до лобі 
Рис. З .2 - Структурна схема лобі 
Система Lobby 
Створення Підкnючення до 
nepCOHaJl..'Y лоб! 
Процес початку 
гри 
Процес перевірКІ1 
готовності клієнтіз 
Почато~: гри 
Рис. З .З - Функціональна схема лобі 
39 
Єntity Enlity 
Сотро1нн1t І Component1 141-__, 
~со"1ро11е1Ф- ..:component> 
Con1poпe11t2 Co1npone11t2 
<co111po11e11t> t-t-------' <component> 
Coп1ponentЗ ComponentЗ 
<co111pone11t:,- <component> 
Cornponent4 Component4 1-1---' 
..:compo11ent> .::component> 
Рис. З .З - Логічна схема системи на основj КОП 
З .1.4 Розробка бази даних 
Провівши· аналіз вимог до бази даних для зберігання даних персонажш 
• ,- • • • • І • • • 
гравцш, важливо зоер1гати даю, таю як 1м я гравця, ршень персонажа, юльюсть 
очків життя та інші характеристики гравця на різних етапах гри. 
Для зберігання цих даних було вирішено використовувати файлову базу 
даних та формат JSON [13]. Це дозволяє зберігати даю гравцш в 
40 
► 
ІІІ' •1·.,,> Оt,р.шн" 1,,,11 ф11рч,11 ~ 
11, 11• ,1t11р,111,щ,1н 1 1 н,, 1 ,, 
\lJ(JJ)\& ,I t 11, ІН І, І . І 1• 1• 1І  ' • •• • 1118* ІМ 
в 
l І І 
I J .. Іі ІН> 
ІІІІ!НІ НН 
1 . J иІ 
) І ~ • н: 
r 'ІШtІр .•, i: t \; , " І J JІ.І.J_ 'J Jf , >.:С,с ~н,н,t І, .... •i J ~··~ І :t .t<.'J ( , f 
ф) 11 ·с 1•і r· r. с 1.сн11н шr 1 с'JІ~· , G,c i не 
.: 
(Jlt." ІН ·•1~ • І І lf І •f#f t ":r • 
,. і ,І (j , t1 і 
ЧДТУ 23 1926.0 І 1 ПЗ 
Рис. 3.4 - Меню головного єr<рану 
Adventurer 
Adventurer server 0.1 1/4 
Back Refresh Create Setect 
Рис. 3.5 - Меню пошуку лобі 
42 
ЧДТУ 231926.О 11 ПЗ 
Lobb 
Player 
Ptayer 
Leave Natready 
Startgame Sel.ect 
character 
Рис. З.б - Меню лобі зі списком гравців 
Рис. 3.7 - Меню створення персонажу 
43 
ЧДТУ 231926.011 ПЗ 
З . І.б Опис розробки програмних . 
компоненпв 
В будь-якому додатку повинна бути єдина точка входу. В роботі було 
використано DI контейнер VContainer [ 14] який допомагає вирішувати 
залежності між різними об'єктами в системі. 
Класс успад~ювані від LifetimeScope - це точr<а входу в модуль в якій 
відбувається ініціалізація всіх об'є1сrів модуля . Кожен клас що наслідує 
LifetimeScope повинен реалізувати метод 
В прое1сrі існують такі класи: 
BootstrapLifetimeScope - відповідає за разову ініціалізацію серв1с1в я1<1 
використовуютьс:я протягом всієї роботи додатку. 
SceneLifetimeScope - абстрактним клас який має в собі ініціалізацію 
потрібних компонентів та сервkів для роботи конкретної сцени. 
LobbySceneLifetimeScope - відповідає за ініціалізацію сцени зі лобі . 
Ініціалізує фабрики об' єктів та їх r<0мпоненти. Також змінює мережевий стан 
програми . 
Так як rюд програми написаний на С# тому різні групи модулів діляться 
на АssеmЬlу(збірки). 
Збірка Advenmre.Core включає в себе такі модулі: 
Інтерфейси IGameObjectFactory та IFactoгy слугують для типізації фабрик 
і зручної роботи з ними. Ці інтерфейси реалізують класи яr<і створюють об' ЄІ<Ти 
динамічно, вони вирішують проблему передачі залежностей динамічно. 
Для завантаження для зміни сцени в Un.ity був створений інтерфейс 
ISceneChanger, він буде мати один метод з параметром jмені сцени . Він 
створений для того щоб реалізувати шаблон "DecшatOl'" [ 16, 19] який вирішує 
проблему додавання нового функціоналу без зміни попереднього. 
NetworkFacade це клас який успадковується від І<ласу NetwoгkМanager із 
бібліотеки Міпо1·. Він виконує роль машини станів де для кожного стану 
програми існує свій клас, який встановлює поведінку при різних подях, таких 
як підr<Лючення гравця до серверу, мережевої помилки клієнта. Кожен стан 
44 
ЧДТУ 231926.О 11 ПЗ 
ділиться на ClientState та SeverState, для виділення окремої поведі1-ши для 
клієнта та сервера. Існують такі стани: 
LobbySeгverState - стан сервера під час лобі. Займається оперуванням 
вхідних підключень та створ енням ·1· х в·щ ображення в меню лоб1·.  
ConnectedCiientState - стан кшє· нта при усш·ш ному шд· 1слючен:юо до 
сервера. Реагує на мережеві помилю,~: та виводить їх на Ul. 
Інтерфейс IConnectiпgType виділяє тип піДІшючення до сервера. Існує два 
типи піДЮІючення: 
ClientConnect - підключення до зовнішнього серверу. 
HostConnect - підключення до внутрішнього серверу. 
Внутрішній сервер - це сервер який запущений разом із додатком та на 
одному девайсі. 
Збірка Adventurer.Scenes включає в себе об'єкти що працюють зі сценою 
та містить такі модулі: 
GameStarter це клас який створюється один раз при запуску гри та після 
ініціалізації Bootst1·apLifetimeScope. Він запускає сцену з головним меню та 
завантажує потрібні ресурси. 
PlayerProvider це сервіс який надає локального гравця для всіх кому він 
потрібен. Він ініціалізується при створені об'єкта гравця, після цього любий 
компонент може звернутись до нього. 
Модуль лобі включає в себе такі компоненти: 
LobbyPlayer - це компонент гравця який має стан готовності, можливості 
запуску гри, та обраного персонажа. Цей клас успадковує NetwoI"kВehavjour 
тому може відправлять RPC та синхронізувати свій стан між усіма клієнтами. 
LobbyPiayei-Factory - клас що реалізовує інтерфейс IGaшeObjectFactory, та 
займається передачею залежностей в клас LobbyPiayeI при створенні. 
LobbyPlayerSpawner - це мережевий об'єкт який створює та знищує 
об'єкти гравців в потрібний момент часу. Також цей клас синхронізує створення 
об' єктів на клієнтах. 
45 
-
ЧДТУ 231926.011 ПЗ 
LobbySceneLoader -
це клас який валідує серnіси перед запусІ<ОМ сцени 
щоб уникнути помилок ініціал·1 зац1·1··  та не1. снуючих посилань на об , єкти. в1· н є 
класом обгорткою над ISceneChangeг. 
LobbyService - сервіс я1с ин~  з б ер1· гас вс1· х 1· снуючих гравщ·в  в ло 5I·  та при 
зверненні перевіряє їх стан готов НОСТІ·  І·  В раз1·  ГОТОВНОСТІ·  ВСІ· Х гравц·ш  запускає 
гру. 
3.2 Тестування системи 
З .2.1 Модульне тестування 
Написання модульних тестів були виконано за допомогою інструментів 
для модульного тестування, а саме: 
Flueпtassertioпs [21] - це набір методш, які дозволяють задати умови 
проходження тестів. Іншими словами, це набір критеріїв, заданих розробником, 
які визначають успішність пройденого тесту. Нижче буде наведено приклади їх 
використання. 
NSubstitute [23] - є бібліотекою для створення підроблених (шосk) 
об'єrсrів у тестуванні програмного забезпечення. Вона надає простий та 
експресивний синтаксис для створення підроблених об'єктів, що дозволяє 
замінити реальні об'єкти у тестових сценаріях. 
NUпit [22] - це бібліотека для тестування програмного забезпечення на 
платформі Uлity. Вона надає розширений функціонал для написання та 
виконання тестів одиниць (unit tests) та інтеграційних тестів для проектів, 
розроблених з використанням Unity. 
Модульні тести розроблялись за методолопсю ААА [24], яка умовно 
поділяє тест на три струкrурні частини: Aпange - підготовка тестових даних; 
Act - виконання бізнес-логіки системою, яка тестується; Asseгt - перевірка умов. 
46 
ЧДТУ 231926.О 11 ПЗ 
0 11.1,1,·1111 •• 
r"bl i c cl,,~~ Pe1·s 1s ten tS1>rvk1•T('•; t s 
{ 
pr· iv,,tc Рсгsі:. t.cnt.Scrvice _pcrsistcntservicc; 
p1·iv,,tc ~t гi_ng _savcsFold!!rPath; 
[ScLUp] 
О Іt'ft.·1 1.·rнt·, 
p~blic void SetUp () 
{ 
_pcrsistentservice = nc1•1 Peгsistentscrvicc(). 
_savcsFolderPath 1 
= $'' {Applicalion . pcrsistcntDataPath}/{Pcrsist.cntscrvicc.SavcsFol d crN ame}"•·  
// Cli,ar s?Іves ( older е\с1·у te~.ts 
if (Directory .Exists(_savesFoldcrPath)) 
{ 
Dircctory .Delctc(_savesFoldcrPath, trнc); 
} 
Рис. З• 8 - Уривок коду ініціалізації тесrування модуля збереження 
персонажа 
Тести для модуля збереження реалізовані в файлі PersistentServiceTests.cs, 
Метод SetUp та його атрибут SetUp ініціалізує поля класі, щоб потім 
використовувати їх · в тестах. Також цей метод використовується для створення 
моків тобто об'єктів які є імітацією якогось інтерфейсу чи об'єкта. 
[Test] 
с rt:ft'r~lllt.'S 
public void WhcnCreate_.длdSelectedSave_ThenCreatesSavcFoldcrAndSaveinтoFile () 
{ 
// ARRANGE . Sclcct savc 
save save = ne1·1 ;:їi!-ve("Tcstsavc", "TEST"); 
_peгsistentService.CurrentSave = save; 
// АСТ. Crcal e save fjlc 
_persistentService .createsaveFile(); 
// дSSERT . Save Fo lсJєгІ11 f о s l10uld Ье creatcd 
Dircctory .Exists($n{_savesFoldcrPath}/{save.Name}") 
.Should() .BeTrue(); 
Filc.Exists($"CsavesFoldcrPath}/{save.Narne}/{PcrsistcntScrvicc.SavcinfoNane} 11
) 
.Should() .6eTrue(); 
} 
Рис. З.9 - Метод для тестування функції збереження 
47 
11 

ЧДТУ 231926.О 11 ПЗ 
з.2.2 Інтеграційне тестування 
Інтеграційні тести для цього пр . . . ... . 
оекту нацщею на перев1рку взаємод11 м1ж 
. ими компонентами та модулями дод 
р1зн атку. 0 сновна мета - переконатися, що 
всі частини додатку працюють разом правильно та співпрацюють 
ерешкодно. Ось декілька приклад1·в 1·нт · ~ • 
безn еграцшних тестш для цього проекту: 
тестування взаємодії гравців· п · 
· ерев1рка, чи правильно працює передача 
даних та комунікація між різними пристроями, на яких запущено додаток. 
f{аnриклад, можна провести тес-rування гри з двома або більше пристроями, 
перевіряючи передачу даних про рух гравців та інші ігрові події. 
Тестування функцій мережевого взаємодії: Перевірка правильності 
реалізації функцій мережевого взаємодії, таких як створення групи гравців, 
приєднання до гри, синхронізація даних між гравцями тощо. Варто 
переконатися, що гравці можуть ефективно взаємодіяти між собою в рамках 
гри. 
Тестування зовнішніх сервісів: Якщо проект використовує ЗОВНІШНІ 
сервіси, такі як сервіси аутентифікації або збереження даних, варто провести 
тесrування їх інтеграції з додатком. Це може включати перевірку правильності 
обміну даними та правильну реакцію додатку на відповіді зовнішніх сервісів. 
Тес'І)'вання локальних режимів гри: Якщо додаток підтримує локальні 
режими гри, наприклад, гру на одному пристрої або режим гри по мережі Wi-Fi, 
варто перевірити, чи працюють ці режими належним чином. Тестування може 
включати перевірку можливості створення гри, приєднання до неї та 
коректність передачі даних між гравцями. 
Тес'І)'вання взаємодії з платформами: Якщо додаток має підтримку різних 
платформ, таких як iOS та Android, важливо переконатися, що взаємодія з 
платформою працює належним чином. Тестування може включати перевірку 
функціональності, сумісності та коректність відображення на різних пристроях 
та платформах. 
50 
ЧДТУ 231926.011 ПЗ 
Ці інтеграційні тести допоможуть підтвердити, що всі компоненти 
додатку працюють разом ефективно та без проблем, забезпечуючи якість та 
І-Іадійність мобільного ігрового додатку. 
З.2.3 Системне тестування 
Для проведення тестування вручну необхідно запустити 2 екземпляри 
лроеІ<ТУ за допомогою Unity Project Cloner [20]. 
1. Тестування меню Лобі 
Тестування підключення до лобі 
Передумови: 
І 
- створене лобі; і · 
Очікуваний результат: успішне підключення нового гравця та 
виведення його в списку гравців 
Виконання: 
Lobb 
Player 
Leave Ready 
Startgame Setect 
character 
Рис. 3.14 _ Нове створене лобі 
51 
ЧДТУ 23 1926 .О 11 ПЗ 
Рис. 3.15 - Лобі n пошуt<у 
Рис. З .16 - Результат підключення гравця в лобі 
З .2.4 Приймальне тестування 
Процес приймального тестування включає декілька критичних етапів, що 
допоможуть забезпечити якість та функціональність мобільного ігрового 
додатку. 
52 
cl)l,'J'Y 2'3 l'J2 (> , <JІ І J І'J 
1J ()'/J;IJ К'/1 Jl)J~ II)' НШ 11/if '/ CC'J)' ЩІJt І/, 
н~ ;J НИ'іІНJІ/ tІІ ' ~•t J')!I'/' , , 
, 1., р<лр<Jvку 111
·1 1:(:.'J'«)1mx ~цснt1рі '( . . . · '' йо, ·о ,,рон ;1,c111m. 
1 1Jf/J1І.-J19 н, ;Jl( J Н/(JIJC,ІJUнr,' IJ • • , 
~ , , y;f;1" (;'J Jj(Jpt.:JІШf кри'І 't:nіїн . . І {;(: ( с р, ·т, UCJ/CJ('/ И' 
A-xr'tf ;;t Ja ,, ОНІ ІІJ{И 'ІН 'І 'С( "J '() · , , , 
r.r?' . J ' , , , . "' · ІІИ Х І(СЙ~ІІІ , 
1) rJ' ,,;Ji JJJAH 'V , JІJJJJ O'JtJHY~ .,.~~·1·<>m1x сср " 
J, 1v ~Nmищ І ·,пус,  , . , 
1/(Щ JХЩІІІ pt:<.:yJ,<.:H )І)/'/ 
,~я. -1 ~с-гунаsтя, lu.. ~ мож~ нютщ;;;.·,·и ' 
,п~П · Н~'J 'Щ/()/Щ<;JІ , , , , , , 
~У• . , , ~ ІІА )Щ)ЩІ І<у lltt НІ/Щ()НJ/(111 
,,rf)ф, f:ГJj{)p<:JJHЯ )ІОJ{ЮІJАІИХ мер~:ж !!t)(J m.u1a111·1·y1J•·•11 • , . . 
1рИ''r , - '.,,, . , . " .. ,, " 11,І Н)'ІОК ДО<.;ТуІІу Wi-Jli , 
JJ;tf.<JИJ.:ШHif J t:C J(JJ_,И½ CIJ.CHc:tpJlJJ Ш()ІІ<>'Ііі< ' Н С •б • 
j ~ )~ JІро, ·рш,ант, 'ШІІJІUJІОШІІ/ИХ 
т~ шо 'fCC'ІYJO'J'J1 рj-щ j аСІ/~/('І 'И 
v-Ф'~ ' , )І,Q/~;;1:/ '/\У, НІ<'JІЮЧШQ'ІИ ЙОІ '() 
'()f!aJІ»HJC'J'J.J, rпа1,;мощю між 1равн.ями 1.  , J . 
lf~~ , , ' ра( >ІІ(у та ·ту,юні сфс,сти . Та~сож 
, ,,nJ]J1ТvCЯ перешрка C'J'Щ)JJIJ.1HOC'J'i та нродуІ<'J'ИНІІО . ,• 
fJP()v/, · СІ І )Ю)І,сІ.'І'І(у, 
1"1омилки та некоректне фунюtіонуна . 
)J, ІІІІЯ ДО/Щ'J'JСУ НЮІВШІJОТЬ під час 
~~rye:,J и н~'  j 1-х фіксують /JJІИ нод.аJ . , 
1 ,ьшо, 0 винранJ1ення. Відстеження 
tИflP'~JІ(:Hb µозво11яе переконатися, що вияuнені нробJІеми були uирішсні і 
J_();J$,,',л о¼,.  л~Ш()Є НаJІе"І'КНИМ ЧИНОМ, 
у-
0(:f~[ОЧН-а оцінка прИЙ.МаJJЬНОJ'О 'J'CC'JYJ"a·,,,,.. зас,100 ~ . · 
І) п • ,.на на резуш,татrв 
1~r;ваиня Fra враховує вимоги, визначені у ностаJювці ~Jавдант,. Ця оці,ша 
M(J'~ вИІІJОЧj{ТИ аспекти, такі як функціональність, стабінм1ість, проду1пиопісп) 
1а 1,0рис-rуваи:ький досвід, Завдяки цьому процесу прийма.11ьноrо тес·rуоання 
'!.~~неJJуеться висок2. якісТІ, та задоволения користуnаt1j 13 від мобіпьного 
іrр<JВОГО до;шrку, 
3,3 Впровадження проrрамJ-Іоrо компJ1с1ссу 
33,1 Розгортання системи 
Серверна частина додатку працює взаємодіючи з клієнтською частиною, 
1ому дли успішного запуску серверу необхідно створити ігрове лоб і, 
виwристовуючи ігровий інтерфейс. Цей тип клієнтів називають "Хост~клієнт11 • 
Вони виступають у ролі господаря гри, керують rеймплеєм та надають доступ 
тшим гравцям до гри через мережу, 
Перш ніж розrо)Уfати систему, важливо завантажити та встановити 
останню версjю Ппіtу - популярного інтегрованого середовища розробки ігор . 
Uпity забезпечує широкий набір інструментів та можливостей для розроб1<и 
53 
ЧДТУ 231926.011 ПЗ 
• р Для успішного розго 
·;1ьJІ1'І" 1ro · ртання також потрібно встановити 
~іо61 
• DK (Software Development к·1t) •nfil S  
6" залежно в.щ  платформи, на яку 
об~І~ 
J!C аі!Уєrься створити ш~ додатку. Наприклад, длЯ розробки на Android 
п!1 тановити Andro1d SDK, а длЯ iOS _ iOS SDK 
1·б J-ІО вс . 
11 ofP • 
ІІісJІЯ завершення шдrотовчих. етапів розгортання системи, настає час для 
. ації проеюу Unity. Потрібно відкрити проект Unity та вибрати 
о!іФ1rуР 
J( • f{)' платформу, на яку планується розгортання гри. При натисканні 
!!еоб~Ід " . . . 
"Switch Platform вщбудеться переключення проекту на вщповщну 
J(IJOJ1 І(}і 
0 №У· якщо доступний фізичний пристрій для тестування гри, такий як 
JJJ1arФ P 
ф н або планшет, ви можете обрати "Run Device" для прямого запуску 
смарт о .. 
на пристро~. 
,цодаrf(}' . . . 
ІJісЛЯ завершення вс1х необхщних. налаштувань, потрібно з1брать додаток. 
f1p« исканні кнопки "Build" - Unity почне процес збирання додатку дЛЯ 
нат 
" платформи. Під час цього процесу Unity збере необхідні файли та 
обрано~ 
необхідні для створення виконавчого файлу гри, який можна 
ресурси, 
ити та запустити на мобільному пристрої. 
всrанов 
р з . 1rr - Меню створення білда додатку 
ис. 'f 
54 
ЧДТУ 231926.0ll ПЗ 
висновок 
у результап проектування, розробки та тестування мобільного jгрового 
1ода·о<У на Unity, було досягнуто поставленої мети - створення кооперативного 
J .., • 
JlOµar r<Y, якии дозволяє грати І<ільком гравцям без доступу до глобальної мереж~ 
іtІ'rернет. Розроблений додаток використовує фу1-шцію "Портативна точка 
e,1ynY w·І -Fi" або з'єдн ання 3 1· ншими спільними локальними мережами, щ о 
µ0 . 
,дозволяє гравцям спшкуватися і взаємодіяти навіть без доступу до інтернету. 
ГІід час проектування було враховано основні вимоги до ігрового додатку, 
raI<i як зручний інтерфейс, плавна графі1<а, добре продумані геймплей та 
фу.нкuіонал. Результатом розробки став стабільний та функціональний додаток, 
.11i<J1Й забезпечує задоволення користувачів і надає можливість насолоджуватися 
J<ооnеративним геймплеєм. 
У процес~ тестування було виявлено та виправлено деякі помилки та 
nроблем:и, що дозволило досягти :надійності додатr<у. 
Отже, в результаті даної роботи було успішно спроеr<Товано, розроблено 
та протестовано мобільний ігровий додаток на Uпity, який дозволяє грати У 
кооперативному режимі без доступу до глобальної мережі інтернет. 
55 
-
ЧДТУ 231926.О 11 ПЗ 
СІІИСОІ( ВИІ(ОРистлних Д,ІСЕРЕЛ 
U11ity З О 
[ Елекrро 11 ни й ресурс] Режим доступу: 
11 І tp~ ://сІос:-1. ш1 іtуЗ d . co111/Manш11/index .html 
2 L~нту О'ІЗ,·іІJп, Вп~се Eckel. Tl,inking in С#. Pientice Hall; December 26, 
20 І З ; Laпgш,ge: Eпglisl, 975 pages lSBN-1 О: 1861008 J 71 
J АшІюісІ NDK [Електронний ресурс] Режим доступу: 
J1ttps ://clcvelopcг.aпdroid.com/пdk 
4 XCodc [Електронний ресурс] Режим доступу: 
l1ttps://dcvctopeг.apple.co111;xcode/ 
5 Aclclt-essables [Електронний ресурс] Режим доступу: 
І,ttps://(iocs.Lшity3d.com/Packages/[email protected]/manual/index 
.І1t111! 
б Мі1тог [Електронний ресурс] Режим доступу: 
J1ttps://mitт01·-11etworking.gitbook.io/docs/ 
7 RPC [Еле1<тронний ресурс] Режим доступу: 
l1ttps://en. wikipedia.oгg/wiki/Reшote_ procedнre_  call 
8 Ашопg US [Електронний ресурс] Режим доступу: 
l1ttps://www.i1111ersloth.com/games/amo11g-us/ 
9 RosenbeI"g D., Scott К. Applicatioп of object шodeling using UML and case 
aпalysis І D. Roseпbeгg, К. Scott. - Рес froш Eпglish. - М.: DMK :Press, 2002. 
- J 60 р. PL1Ьlisl1er: Addisoп Wesley First Editio11 June 14, 200 І ISBN: 
0-201-73039-1, 176pages 
10 VjsLial StL1dio [Електронний ресурс] - Режим доступу: 
l1ttps://learп.microsoft.co111/en-lls/vist1alstнdio 
11 DI [Електронний ресурс] Режим доступу: 
l1ttps :// ев. wikipedia.oгg/wiki/Depeпdeпcy_  inj ection 
]2 СОР [Електронний ресурс] Режим доступу: 
l1ttps://en.wikipedia.org/wiki/Component-based_software_engineering 
І З JSON [Електронний ресурс] Режим доступу: 
l1ttps://www.jso11.org/jso11-eп.ht111l 
56 
ЧДТУ 231926.0JI ПЗ 
/4 VContair1c1' 
[Еле1пронний ресурс] Режим доступу: 
llttps://vcoпta і пе1·. l1adasI1і  kick.jp/ 
5 Reshш·pe1· 
J [Електронний ресурс] Режим доступу: 
J1ttps://www.jetbгains.com/гes1щгpeг/ 
16 KISS, DRY, S.O.L.I.D, YAGNI - [Електронний ресурс] - Режим доступу: 
I1ttps://seпio1·. L1a/ar·ticles/kiss dгv -so 1· І • · · · 
- J 1с -yagш--пavscl10-dot1·iшнvat1s-pпnc1pv-p 
1·og1·am11vaпnya 
17 UDP (Еле1<тронний ресурс] Режим доступу: 
І1 ttps://е п. wikipedia.01·g/wiki/Useг_D atag1·a111_ Protocol 
18 ТСР [Електронний ресурс] Режим доступу: 
https://en. wikipedia.01·g/wiki/Tгans111ission_ Coпtrol_P1·otocol 
19 Robe1·t Nystгoin. Game Ргоgга111111іпg Patteгпs - [Еле1<Тронний ресурс] -
Режим доступу: https://gamepгogi-aiшningpatteп1s.co111/ 
20 Unity Project СІоnег - [Електронний ресурс] - Режим доступу: 
l1ttps://gitl1t1b.com/hwaet/UnityPгojectCI011eг 
21 FlL1e11tasseгtio11s - [Елеr<Тронний ресурс] - Режим доступу: 
https://flueп tasseгtions.com/ 
22 NUnit - [Електронний ресурс] - Режим доступу: l1ttps://nнnit.oгg/ 
23 Nst1bstitL1te [Електронний ресурс] Режим доступу: 
]1ttps://nsubstitute.githL1b. іо/ 
24 Vladi1nir Kl1oгikov. Uпit-testiлg. -(2020) Language: English 320 pages ISBN: 
9781617296277 
25 Метод.ичні реr<0мендації до пjдготовки J<валіфікаційної роботи бакалавра 
для здобувачів вищої освіти зі спеціальності 12] «Інженерія програмного 
забезпечення» усіх форм навчання [Текст] /Укл.: Голуб С.В . , Заспа ГО., 
Півень о·.Б. Катаєва Є.Ю., Салапатов В.І., Метелап В.В., Олексюк В.В. ; 
М-во ос.віти і науr<и України, Черкас, держ. технол. ун-т. - Черкаси : ЧДТУ, 
2023. - 97 с. 
57 
ДОДАТОJ( А 
ЗАТВЕРД)КЕНО: 
(афедри ПЗАС 
с.в. 
ПРОГРАМНЕ ЗАБЕЗПЕЧ ЕННЯ КООПЕРАТИВНОГО ІГРОВОГО 
МОБІЛЬНОГО ДОДАТКУ НА ОСНОВІ UNITY 
Специфікація 
482. ЧДТУ.23 І 926-0 І І ПЗ 
Листів І 
Розробник ~ Чуплий М. А. 
Керівник ~ Первунінський С. М. 
Н. Контроль ~ Півень О.Б. 
Черкаси 2023 
2 
Позначення 
Найменування Примітка 
г 
докхментаgія 
. 4g2. ЧДТУ23 1926-01 1 1? -01 Лістинг програми 
, 482. ЧДТУ23 І 926-О 11 34-01 -
Інструкція користувача 
482.ЧДТУ2319?6-ОІІ 90-01 -
Графічні матеріали 
-
-
-
59 
ДОДАТО:КБ 
ПРОГРАМНЕ ЗАБЕЗПЕЧЕННЯ КООПЕРАТИВНОГО ІГРОВОГО 
МОБІЛЬНОГО ДОДАТКУ НА ОСНОВІ UNITY 
Лістинг програми 
482.ЧДТУ231926 12-01 
Листів 60 
Розробник - ---P~':.J7D---- Чуплий М. А. 
Черкаси 2023 
■ 
p10J,•1 ( ' '\1 , І ' 10l)l" 1 І "J] 
І 'l•11Jl11t· I Іl' I J 1 \11
· " .tk ЛJ, l'ІHlІГL'r '\° •1\  k І) 
~ ,щ r lO\ Г) drч.o,.:f'I. 
1s ~1,.,11/\.:J 1l'IJJ 1ч 1,.Jtl· ,L.1\ 1 1. d · 
ш ... Llt,\ l" lll"l"Llf J Jt:,t1.k. 
І \,•1 І.JІІІL' І Іt· ld j !)П\ JI\.: L І) j 1 · 
• ,н 11!;, ІL'.:11\ 1\:\\ k •L1d1n~'-;c11.:t"11 \- 1L'\'. 
[ Jk;1Jcг("SЛ\Іf MOD LE")) 
t:L·ri:1 l 11t+їcld J 1xi\·~1tc ЬооІ _щ;сJ:юпS:.нс~ ; 
Jte~istcгMainM odule(b u іІdсг) ; 
Register·S ·е,н~s( bui ldcг); 
bui ldL'r. Re gisteг<Opeпlt ioпloader>( Li fe ti те .Siпgl eton) 
.\ ~' і tl1 Parш11ete1·L l1):.1d i11gScrcen Vic,v); 
Ь11 і ltkr. J{ L'g_i:-;tL' i"C 01111ecteJCI іслt 1:1te>( Lite1i111e.Si11gleton) 
. А~ 'eЩ).A~lmpk111~11tccil11te1·Г.1ce (); 
btJi\der. l~ egi. terEn try Poi111<Gu111eS t:.1rter>(L і tctime.Si11gleto11 ); 
рт ut1: , oid Rc~istc,·Maiв 1o(lttk (IC011taiнerl.З\1ilder builc\c1·) 
b11ilder.l< cgi tL'1Co111p(.).nc111 ( lli :.t:O\'CJ')' ) 
.As1щрk111Clll cul 11tL'Гli11.:L'S( ) .А ss~ 110; 
61 
І ' 
d 
pr otectcd oveпide ,,oid Соп fіgнгс ( l Cot\\', І•\І \с,1  _1o1t 11• kk1· t,ш•І ~k,·) 
( 
ьase.Configш·e(buildeг) ; 
RegisterSei-vices(buildeг}; 
RegisterUI(bLІildc1·); 
RegisterPlayeI(builde1-); 
bui\der.Registeг<LobbySen1e1·S ta te>(L і tct·i ~не. Sc()pc<I) 
.AsSelf().Asiшpleшeatedl1\te1·t'acc:;(); 
private void RegisterUI(IContai11c1-Внilde.- bt1ildeг) 
builder.RegisterCompoпeп tLІ оЬ Ьу \Tie"v ); 
buildeг. RegisteICompoпen t(_с  Іш гacterSelect іон) ; 
builder.RegisterCoш ропепt(_гасеSеІесtіоп М е1ш ); 
private void RegisteгServices(IC011tai11erBнilde1· lюildcг) 
{ 
builder.Registe1-<LobbySeгvice>(Lifetime.Scopeti) 
.AsSelf().Asl111plementedI11teгfaces(); 
private void RegisterPlaye1· (1Containei-Builde1· bt1ildeг) 
{ 
bt1ilde1.·. Registe1<PlayeгP1·0,,ide1-<Lobby Р laye1·>>(.Li f'eti 1не . Scopecl) 
.AsSeЩ).AsTшplemeпtediпteгfaces(); 
63 
І 'І.'!.!.і ~ І1: LobbyPl.1ye1·.fiJc tuгy::.. ( Liktiн,,.. , d 
,І J(І · " ~ 1.:. , сорс ) 
І'\ . 11,.JrJJПCtt:r(_playcrPrcfab) 
\~ 1І І ' 
,. hp;11-irt1CterL.PlaycrSpa\\1nPo іtі оп) 
,, 11 
J.~ .:ІfС ).As l тple111entedJ1нcгfaccs(); 
bLІjJdcr.Rcgi ster<Lobby р laycrS ра ,vner>(Li rc t і те . Scopcd) 
.AsSclf().Aslmple111entedlntcгfaces(); 
ьuiІder.Register<U 11 i tyfactoгy<Cl1aгacteг>>(Lifetime.Scoped) 
\VithParame!'er(_ cl1aractcrPгefab) 
.W i t11Para meter(_c haracterSpa, v11Posi tion) 
.AsSeJfO.Aslmplementedlпterfaces() ; 
ьuiІder.Register<CharacterSpa wn er>(Li re ti ше. Scoped) 
.AsSc/f().Asf mpleinen ted rn tertaces(); 
·ivate void Start О 
var netwoгk = Coпtaineг.ResoJ,,e<Net,voгkFacade>(); 
net,vo1·k.SetState(Co11taiпeг.ResoJve<LobbyServe1·State>()); 
ne1,vork.SetState(Contai11er.Resolve<Co1111ecte(iClientStatc>()); 
1e1,vork.S t artN etw ork(); 
1a111eplaySceneScope 
се Adve11tul'eг.Sce11es.Gameplay 
64 
482.ЧДТУ.231926-011 
ь\'с 
6 
class GaineplaySceneScope. Sc L' . 12-01 
pi1 1 · ene 1fet11пcScope 
[scria\izcFicld] pгivate Lcvc\Sciv ic _ 1 . 
е с,,еІSсг,,1се· 
' 
[serializeField] pгivare GaineplayP\ . 
. . . ayei _playeгPrefab; 
[seгia\1zeF 1eld) pпvatc Тгапsf01111 _ра, 1. спt ; 
[Seria\izeField] pгivate СІ1ап\сtеr - chai·a,  cter р l'efab; 
[SerializeField] private Traпsform _рІау er СІ iaгacte1·Spa,vnPositio11; 
[SerializeField] pгivate Cl1aracter _cпemyPi·efab; 
[SerializeField] pгivate T1·ansfo1111 [] - епе111уs pa,vnр  0s1.t1. 0ns· 
[SerializeField] p1·ivate Transfon11 _еnешуРаІепt ; ' 
pi·otected o,1erride void Configui·e ( 1Coпtn i 11crBнi ldcг builder) 
{ 
base.Configшe(Ьнilder); 
/(Registe1·Spawners(Ьuilder); 
buiІ сІеr. Register<G ашер \а ySeгverS tate>(L itet і 111e.Scoped) 
.AsSelf().Aslшplemeпtedl11tcrfaces(); 
builder.Register<PlayerProvider<Ga111eplayPlayer>>(Lifetime.Scoped) 
.AsSelt'Q.AsI111ple111entedlntert'aces(); 
bнilder.RegisterCon1po11entl_Іe,1elService); 
protected overгide void RegisteгSpa,:vne!'s ( \CoпtainerBuilder builder) 
builder.Rcgister<UnityFactory<Cha1·acteг>>(Lifeti111e.Scoped) 
.W itl1Paraшete1·l_c haracterPrefab) 
.W i t·hParaшeter(_playerCharacterS pa,1/nPosition) 
.AsSel f() .Aslmple111entedln te1-faces(); 
65 
7 
, 11. І Ji;i·, I< щ:ін І ~.: 1 ·· · ( i11111i.:p/11y l'/11yi.:,·, 1::,vio,·y, ·І/ 
1 ,,, / 'v l1.1 111:,S,, ;opщ l) 
11
, wн11/ІІІІ'НІ11Сf СІ'( рІ11ус1·Р1·1.: /і1/)) 
Wif/JJ'lfl'ІJ 111 cf t:1'(_pнпml) 
,f\ .~si.:І tr).Лs l І 11р/стс11 fC(// 1І  fc1·/;1ccs( ); 
1 .1 ,1,.;,·. І< cJ; is f cJ'<Ci 11111cp l:1yl'/ayc 1·Spaw,ic ,>·( I- 1•, ·t :t .11 11t:,S,c 1111 .:upt:,IJ 
,f\ЯSv l І() . Л к І I пр Істс11tщІ І 11Іu1·/iic.:cs(J ; 
/JtJi/ с/сІ'. Н cgislc1-<E11cmySр а w11c1·>( /.,і /(;ti mu.Scopc,I) 
.W it/1/1,11·amctc1'(_ с11с111у Р,·сfі1І,) 
. Wit11P111·шnc/·c1·(_ спс111уРш·с11t) 
. Wit/1P1.m1mct1,;1·(_ 1,;11cmySpaw11Posilioп s) 
.лsScl {(),ЛsІ трІстсп Ісс/ l 11 tc1·/ i1ccs(); 
pri vatc void Staгt О 
vпг пс1wо1·1< = CoJJta i11cг.Rcso/ vc<Nc1wol'kГacadc>(); 
11ctwo1·k,ScLStнtc(Co11t,1i11e1·, Rcsol vc<GamcplaySc1·vc1·S1a1c>()); 
Nclivol'kC!ic11t.Rcady(); 
StartCoJ'ouU11e(Spaw11i11g()); 
pl'ivate IE11u111eгatoJ' Spaw11iпg () 
yield 1·еt11гп пе\1/ WaitForSeconds( l О); 
forec1cl1 (vаг со,ш іл Netwol'kSeгveг.coппectio11s.VaJнes) 
vаг рJауег = Co11tai11e1·ЯesoJve<Ga111epJayPJayeгSpaw11e,.>().Spaw11(coлл); 
66 
482 -ЧДТУ.231926-0 l l 12-01 8 
playei·.CІ1ai·acte1" = с 011tai11eІ".Resolve<Cl1ai·acteгSpawнc1·>().Spn'rv11(new 
characterSpawnAl"gs()); 
} 
файл Netv\101·k.Facade 
пamespace Advcntt11"eг.Co1·e.Net\.vork 
public class NetwoгkFacade : Net,1,101·kMa11ager 
public ISceneChange1· SceneClшпger { get; set; } 
рнЬІіс IConnectingl'ype ConnectionType { get; set; } 
public Sei-veгState SeГ\1e1·State { get; pri,1ate set; } 
public ClieпtState ClientState { get; pl"ivate set; } 
[fпject] 
рLІЬІіс void Coпstшct (ISceneChaпgeг sceneCl1ar1ge1·) 
Sce11eCl1anger = sceneCliaпger; 
public void SetState (SeгveгState serYe1-State) 
Serve1·State?.OnExit(); 
SeгverState = serverState; 
if (NetworkServeI".active) 
ServeгS ta te. О nE n ter(); 
67 
► 
. 482. ЧДТУ.23 І 92бw0 І І 12~0 І 
piibІic void SelState (C\1e11tSl11te clicн\Stнlc) 
{ 
ClieпtStatc? .О11Ехі t(); 
ClieпtState = сІ ie111Statc; 
it' (Net"voгkCI ieпt.act Ї\1С) 
C\ie11tStatc.011E11Іc1'(); 
pt1blic ,,oid StaгtNetwo1·k () 
it' (Con11cctio11Typc.Not Ех ist()) 
tl,гow пеw Systcm.№1\IRcf'cп:11ccExccptio11("Co1111ccliш1 Lyp<.; і к not ~clLcu і11 
Net,vorkFacade"); 
Coппectio11Typc.Connect(); 
switcl1 (inode) 
case NetworkManagerMode.l-lost: 
SerYe1·State.OnE11tcг(); 
ClientState.011Ente1·(); 
Ьгеаk; 
case NetwoгkManagerModc.Clic11I011ly: 
Clic11tStatc.011Eпter(); 
break-
' 
casc NetworkMaпagcrMode.ServerOnly: 
throw пеw Systeш.JnvalidOpcrationExceplioп("Game cannot run servcr instaлce"); 
default: 
Debug.LogError("Caп1юt stop 11etwo1·k facade wl1en it is not .ictivc"); 
Ьгеаk· 1, 
' 
68 
482.ЧДТУ.231926-011 12-01 10 
'-\ і~ \,оісІ Stop О 
рІІІ' 
І 
\ 
casc Net,vorkMaнagcrMode.Нost: 
StopHost(); 
ьгеаk; 
cnse Net\\1oгkl\1lanageгMode. СІ ientOnly: 
SюрСІіепt(); 
brcRk; 
cnse Net\vorkManagerMode.ServerOnly: 
StopServeг(); 
bt·eak; 
defaнlt: 
Oebнg.LogEгroг(11Cannot stop net\voгk facade wl1en it is not active"); 
b1·eak; 
pt1blic o,,erride void OnCLieпtClшngeScene (string newSceneName, SceneOperation 
sceneOperation, ЬооІ customHandling) 
base.OnClientChangeScene(ne\vSceneNaшe, sceneOperation, customHandling); 
if (custo111Ha11dli11g = fa lse) 
retuш; 
if (NetworkServeг.active) 
Іеtнш; 
SceпeCl1anger. ChangeScene( newSceвeNaine); 
Public о,,епіdе void OnSer,,ei·Coвnect (NetwoгkConnectionToClieпt соnп) 
69 
4R2. ЧДТУ.211926-0 І І 12-() І І І 
І 
1 
s~rv~· i·St,·i t~ .О 11СІ і~нtСощн:сt,х.1'1  ~:01щ)·,  
scrvCІ'Statc.011ClicшDiscoпн~cted(coш1) ; 
public ovcпidc ,,oid ОнSс1,,с1·Rсщ\у (Nct,vo1-kC01111cctio11ToClie11t сопп) 
ServcrS tate. Оп СІ ient Ready( сош1) ; 
рнЬІіс oveпide void O11ClientSce11eClш11ged () 
base. О11СІ ie11tSce11eCha11ged(); 
public ovc1тide void OnClientNotReady() 
ClicвtState.OnNotReady(); 
public override void OnClientConпectQ 
ClientState.Connected(); 
pub\ic oven·ide void OnClientDisconnectQ 
{ 
ClientStnte.Disconпected(); 
} 
PUblic oveгride void OnClientE1тo1·(T1·anspoгtEr1·0r еноr, st1·i11g i·eason) 
70 
482,ЧДТУ.231926-01112-0l 12 
{ . tState ОnЕпо1-(е1тоr, reaso11); 
С\1еП . 
І ~ 11.iet\vorkState 
фаНJ1 i-i 
Advc11ture1".Coi-e.Net,voгk 
ace 
11ntJlCS p
І • abstract class Se1·ve1·State 
рнЬ1 1с 
І 
public abstJ"act void О11СІ icntC01111ected (Nct\\'OI"kC01111cctio11ToClicnt со1111); 
ptiblic abstract void OnC\ientDisconnected (Net,vorkConnectionToC\ient conn); 
public abst1·act void OnCJieнtReady (NetworkCon11ectionT0Client conn); 
public abstt·act void OnE11te1· О; 
public abstгact void OnExit (); 
public abstшct class ClieпtState 
public abst1·act void 011E11ter (); 
рнЬІіс abst1·act void OnExit (); 
pt1blic vii-t1.1al void OnErюr (TransportError error, sti-ing reason) { } 
public virtш1I void OnNotReady О { } 
public virtLtal void Connected О { } 
public vi1·tual void Discoпnected О { } 
} 
j 
Файл IConnecti11gType 
nat11espace Adve11tuгe1·.Co1"e.Netwoгk 
{ 
public iпterface IConnectingType 
{ 
void Connect(); 
71 
-
482 .ЧДТУ.231926-0\ l 12-01 13 
pt·iyнt~ 1~нlІо11\у Nct,vo1·kГ-acade _нet\\'OrkFacade ; 
pt·i\' t1tc 1·cнllo11ly st1·iнg _addrcss; 
pttblic ClicntC01шcct(st1·iнg ac\d1·css, Net\,101·kFacade пet,vork.Facade) 
_ нct,Yo1·k Facaclc = 11ct,vo1·kFac<1dc; 
_add1·css = address; 
\ 
' 
pttl)lic \loid Co1111ect() 
_net,,1orkFacade.пet\vorkAdш:ess = _address; 
_11et,vork.Facade.Sta1·tClie11t(); 
public class HostCoш'lect : IConnectingТype 
pri,1c1te 1·eado11ly Net\\1oгkFacade _11et\.\101·kFacade; 
public HostConлect(NetwшkFacade нet\.VOl"kfacade) 
пenvorkf acade = netw01·kFacade; 
public void Conпect() 
{ 
nenvoi-kFacade.StartHost(); 
} 
72 
482.ЧДТУ.231926-011 12-01 14 
влsrю ON 
і/І . 111  ,Ь com/U1\ity-Tcclшologics/нщltipli1 . . 
hlll'~://git • • • • yci-coщпшщty-coпt1·ibt1tio11s/11·cc/11111i11/co111 .co111111 
. iietcotte.cxtcm;ю11s/H.ннt 11пe/Nct "'oi·k І)і~со,,с,·у 
11111ІУ· 
JI/ .QS\111111\lll'Y> 
• \І S)•:;\C\\1: 
11~111::-
.. \\! sys\CІ)) .IO: 
,,~11. 
i1si11g System.Net; 
. , sys1c111.Nct.Sockc1s; 
\1$111!; 
ІІSіtІЦ sу:;1с1н. Н.ннtі те. Sc1·i11 Ii z11tioн.F01·11нittc1·s. 13 і,ш,·у; 
11~інц Sy:;tc1н.T\11·catliнg.Tш;ks; 
115j11g U11ityE11giнc; 
si11g Rанdо1н = U11ityl21\gi11c.Raнdo111; 
11
113111cspacc UDPNct,vo1·k Discovc1·y 
[Disnllo\\1MнltipleCon1po11e11t] 
рнЬІіс abstп,ct с\ш;s Nct,vo1·kDiscovc1·y<TBroadCnst, TRcspoпse> : МопоВеІщvіош 
\\1І1с1·с TBюaclCast : 11с,.,1() 
\Vl1c1·c TI<..cspoвsc : пс,v() 
p1·ivate епшп McssngeType : byte 
Bюac\Cast = О, 
Іicspoвse = І , 
UdpClieпt 111 С\іевt; 
[Seгial izeF ield] t1sl101·1 ш_Рогt = 47777; 
// Tl1is is 1011g becattsc t111ity i11specto1· does 110t like t1Іонg. 
[SerinlizeField] 
Іопg l\1_UпiqнcApplicatio11[d; 
73 
4Н2. Ч)~ТУ.23 1926-011 12-0 І І 5 
/// .(SUІ11ІШ.ІІ'У> 
ІІІ act~ н val ttc i11dicatini:: wl1ct11c1· tl,c ,ІiscuvС,І.  У . ' І !і.  1'111111 .ІІ 1g, 
ІІІ ✓.::/s11111ina1·y> 
pii\Jlic bool lsJ{t11mi11~ f gct; p1·ivatc м:t: , 
ІІІ <sum111ш·y> 
ІІІ Gcts wl1ctlю1· tl1c di:-;covc1·y is іп i-;c1·vcr тщk:. 
І/І <ISt1111111Ш'Y> 
public buol l sScгvc1· { gct; privatc sct; } 
ІІІ <summary> 
/11 Gets \vl1etl1e1· thc discovcry is in cli ent modc. 
/// </sшnmary> 
public ЬооІ lsClicnr { gct; privatc sct; } 
public void OnApplicationQuit() 
StopDiscovery(); 
void OnValidate() 
if (ш_UniqucApplicationid == О) 
var valuel = (long)Raпdom.Range(iнt. MinYalue, int.MaxYalнe); 
var value2 = (long)RandomЯange(int.Mi11Valt1e, int.MaxValue); 
111_U niqueApplicationid = value І + (value2 << 32); 
public void ClientBroadcast(TBroadCast broadCast) 
ir (!IsClient) 
{ 
74 
-..С..- -
. 4~2.Ч ДТУ.2З 1926-01 І 12-0 І 16 
tliro,v 11e,v Inval1dOperatio11Exception(''C, . . . 
. tnnot send cl,ent broadcast w/1ile 11ot пinnmg ш 
de СаІІ StartCI 1ent fiгst. ")· 
не11! 1110 . ) 
JPEndPoin[ endPoiпt = пе"' IPEпdPoint(IPAdd . В d 
ress. roa cust, m_Por·t); 
нsіпg (,1ш· sr1·ca111 = пеw Mc111oryStrcarn( t 024 )) 
{ 
Writel-:leadeг(stгeaш, MessageType.BroadCast); 
var binaryForшatter = ne,v BinaryFormattcr(); 
bi11aryF011пatter.Serializc(strcarn, broadCast); 
vai· data = streшn .ToArray(); 
tту 
{ • І 
m_C lient.SendAsync(d ata, data.Lcngtl1, eлdPoint); 
catcl1 (Exceprion е) 
{ 
Debug.LogError( е); 
} 
,· 
} 
ІІІ <sunш1ary> 
ІІІ Starts tl1e discovery in server шоdе \Vl1ich ,vi/1 respond ro clienl broadcasts scarcl1ing for 
sen•ers. 
ІІІ </summary> 
public void StartServer() 
{ 
BeginMulticastLock(); 
StartDiscovery(true); 
ІІІ <strmmary> 
75 
-
. . . :82.ЧДТУ.231926-011 12-01 17 
S_t.,\  ri·,  tІ,е ti1st'OYery 111 с\1епt mode. <see cref-="Cl.i entBroadcast"/> can Ье called to send out 
•. :;t:..  ю sc:i,=eГ-> апd tl1e client \Yill acti\'e\\r list""n fi 
t J  or responses 
~1,.1\. "1" • 
~1\ . < 1> 
:;\J\\1111~ 
pub\ic ,·oid StartClie11tO 
public ,,oid StopDiscoYery() 
EndpMulticastLock(); 
IsC\ieпt = false; 
IsSerYer = t"alse: 
IsRunni11g = false: 
іt" (ш_C lient != null) 
t:ry 
{ 
m_C lient.CloseO; 
} 
catch (Exceprion) 
// \Ve don't care about socket exception hcre. Socket ,,,ш al,vays Ье closed after iliis. 
} 
m- Client = null·'  
ІІІ <summary> 
ІІІ Gets ca\led ,,,henever а broadcast is recei,1ed. Creates а response based on the incoming 
broadcast data. 
/// <lsummary> 
11 < param name="sender">The sender of the broadcast</param> 
76 
і 
482.ЧДТУ.231926-0 l l 12-0 І 18 
-~ro oame="broadCa5t">Т hе broadcast data \Vhich \\'as sent</param> 
., ~р .... ~ 
. _,.,.,, name="response">The response to send back</param> 
,, ~Pi1' .... -
~,rns> тrue if а response should Ьс sent back else false</returns> 
•1i .:::reL,... •. 
ected abstract bool ProcessBroadcast(lPEndPoint sender TBroadCast broadCast, out 
pr0 1 ' 
. nse response); 
1RPI'° 
'1/ .(Summary:> 
Ш Gets ca!led \,,Ьеn а response to а broadcast gets received 
і/! 4 5urnmary> 
!f/ <param naroe="sender">Thc sender of thc response</param> 
,;'f <param name="rcsponsc">T he value of the response</parnm> 
proiected abstract ,,oid ResponseRecei,1ed(IPEndPoint scnder, TResponse response); 
\'oid StartDiscovery(bool isServer) 
StopDiscovery(); 
JsServer = isSeГ\'er; 
IsClient = !isScrver, 
/І J[\ve are not а seп'er \Ve use tbe О port (let udp client assign а free port to us) 
var port = isServer? m_Port: О; 
m_C lient = ne,v UdpClient(port) { EnableBroadcast = true, MulticastLoopback = false };  
= ListenAsyoc(isSeГYer ? ReceiveBroadcastAsync ne,v 
Func<Тask>(ReceiveResponseAsync) ); 
IsRunлing =t rue; 
аsулс Task ListenAsync(Func<Тask> onReceiveTask) 
{ 
,vI1ile (true) 
{ 
77 
.11 :.t'i!l.clll - 1 .с\\ \н .,~ :н·:11.n11•Ь :, t с .,,\ .. p!{C'l. .:-•• cR.:-• -·:B- H, ~ .І, 
.,.;. , ~н rl~ c- u! І Butiat .-t'п~1J11, 
,:sr Ьт.11') J ~mull i:І n,, Н1РЧ'І 1 11 .. , ( t. 
р. i:, п~сRнс~, N udrR~ 1, с ~ u\\ R~tti( ~~EndP01nt. 
482.ЧДТУ.231926-011 12-0 l 20 
} 
catch (Exception е) 
{ 
pebug.LogException(е ) ; 
asYl1c Task ReceiveBroadcastAsync() 
lJdpReceiveResolt udpReceiveRcsн\t = av-:'a it 111 _c i·1 e11t. R ece1. veAsyncO; 
var segment = ne,v AпaySegment<byte>(udpReceiveResult.Buffer, О, 
udpReceiveResult.Buffer. Lengt\1); 
try 
usiпg (var streaш = new MeпюryStream(segшeпt.Aпay)) 
if (ReadAndCheckHeader(stream, MessageType.BroadCast) = false) 
{ 
· retur11; 
} 
var binaryfo rmatter == ne\\' BinaryFoпnatrerO; 
vai· broadcast = (TBгoadCast)binaгyf 01·matteг.Deserialize(stгea111) ; 
if (ProcessBroadcast(udpReceiveRest1lt.RemoteEndPoint, broadcast, out TResponse 
response)) 
{ 
нsing (var seпdStreaш = new Memo1-yStream(l024)) 
{ 
WгiteH eade1·( sendS treaш, М essageType. Response) ; 
binaryFormatter.Serialize(sendStream, response); 
var clata = sendSt1·eюn.ToArray(); 
79 
482.ЧДТУ.23 І 926-0 І 1 12-01 21 
await m_Client.SendAsync(data, data.Lengtl1, 
. Result.RemoteEndPoint); 
~eceive 
~dP } 
} 
catcl1 (Exception е) 
Debog.LogException( е) ; 
private void WгiteI-Ieader(Sti:eam \Vriter, MessageType messageType) 
var bytes = BitConverter.GetBytes(m_U niqueApplicationld); 
\Vriter. Wr i te(Ьytes); 
,v1·iter. WгiteByte((byte) messageType) ; 
private bool ReadAndCЬeckНeader(Stream i:eader, MessageType expectedType) 
vai· bytes = пеw byte [sizeof(long)] ; 
reader. Read(bytes); 
var receivedApp1icationld = BitConverter.Tolnt64(bytes); 
if (recei,,edApplicationld != т_U niqueApplicationld) 
{ 
return false; 
var messageType = (byte) reader.ReadByte(); 
if (messageType != (byte)expectedType) 
{ 
ret11m false·,  
80 
482.ЧДТУ.231926-011 12-01 22 
// лndroid Mt1lticast tix: l1ttps://gitlшb.com/vis2k/Miiтoг/pt1ll/2887 
. •f'tJNI'fY _ANDROID 
#i лndi·oidJava оь·J ect 111·t•u t·1 castL o ck; 
ьооІ 11asMнlticast"Lock; 
#c11dif 
void вegi11Mt1lticastLock() 
{ 
#if uNJТY _А NDROID 
if (ІшsMulticastLock) геtшn; 
if (Application.platfo1·m == Rtшti111eP\atl'orn1.A11d1·oid) 
{ 
using (A11d1·oidJavaObject activity == new 
AndroidJ ava СІ ass(" сот. tІ 11 і ty З d.р  І аy er.U  n і tyP laycr").G etS tatic<A11dro idJ avaO Ьj  ect> (" cu ,те nt  Ас ti 
vity")) 
{ 
нsing (var wifiMa11age1· == activity.Cal\<AndroidJavaObject>("getSyste111Se1-vice", 
'lvifi11
)) 
{ 
1шilticastLock == wifiM aвager. Са 11< A11dl'OidJ avaObj ect>("c1·ea teMul ticastLock", 
"lock"); 
1ш.1JticastLock.Call("acqt1iгe"); 
hasMulticastLock == true; 
#endif 
void EndpMt1lticastLock() 
81 
482.ЧДТУ.231926-О 11 12-01 
f 
l 
. . ,.-ry A}IORO[D 
,,·t t}NІ 1 -
,1 1· r ('. hasMulticastLock) retum•,  
111ulticastlock'?. Са 11 ("release"); 
JiasMнlricastLock = false; 
1 
J . 
✓ 
Файл Scenef\,fanagerWrapper 
using Systeш.Тl1reading.Tasks; 
using UnityE ngine.SceneManagement; 
nan1espace Ad\·enturer.Core.SceneManagemeпt 
{ 
public sealed class SceneManager\\7rapper : ISceneCbanoer 
.::, 
priYate string _ cшrentScene; 
public async Task ChangeScene (string sceneName) 
{ 
a,vait UnloadCurrentSceneQ; 
a\vait LoadScene(s ceneName ); 
pri,;ate async Task LoadScene (string sce11eNa111e) 
var asyпcOperation = SceneManager.LoadSceneAsync(sceneName, 
LoadSceneMode.Additive) ; 
,,,hile (!asyпcOperation.isDone) 
a,vait Task.Delay( 1О О); 
82 
482.ЧДТУ.231926-011 12-01 ?А 
cuiтcntSceпe = sсепеNашс; 
private asy11c Task Un1oadCt1rreпtScene О 
if (st1·i11g.IsNt1l\01·EшptyLc щтcntScenc )) 
va1· nsy11cOpe1·atio11 = SceneManageг·U nloadSc ene А sync Lc urrentScene); 
,vl1ile (!c1syncOperatio11.isDone) 
await Task.Delay( 1О О); 
І 
} 
Файл NetworkSceneMaпagerWrapper 
пainespace Adventшer. Со!'е. SceneManageinent 
public sealed class NetworkSceneManagerWrapper : lSceneCl1anger 
pгivate геаdопІу JSceneCha11ge1· _ w1·apper; 
public NetworkSceneMaпagerWrappeг (ISceneChanger wrapper) 
{ 
} 
public async Task CЬangeScene (string scene) 
{ 
await _w1·apper.Cl1aпgeScene (sсепе); 
83 
482.ЧДТУ.231926-Оl l 12-01 25 
)'Jer.vo1·kServeг. S ра Y.'n Obj ects(); 
Net\vorkServer.Se11dToA\\(11e\Y SсепеМ essnge 
{ 
sceneName == scene, 
custo1uHa11d1ing = trнe 
} ); 
if (NerNoгkClient.active) 
Ne tworkCI іеп t. Р rераге ToSpa \.vnSceneObjectsO; 
Файл PeгsistentSeгvice 
namespace Adventurer.Modules.Persiste11t 
public class PersistentService 
public const string Savesfo \derNaшe == ".Saves"; 
public const string SaveinfoName == "lnfo.sv"; 
public Save Curre11tSave { get; set; } 
public static string SavesFolderPath 
{ 
get => Application.peгsisteпtDataPatlt + "/" + SavesFolde1·Naшe; 
pub\ic void CreateSaveFile () 
{ 
84 
\' :lf p:-it\1 = S" ( Saн·sFoldcrPatl1 } / 1
' Cшн:111S1, \'-•'. .,, ,,..1 1 11с,, " •·  
if (!Dir~cюry.1.:xi:-ts(pзtlt)) 
reшm; 
Directory.Dclctc(patl1); 
public І Enumerable<S,н•e> GctSa,•cs () 
if (! D irectory. Ехі sts( Sa\•esFoldcrPatl1) ) 
Directory. Create Di recюry(SavcsF old~rP::itlt ): 
yield break; 
s1тing О saYef olders = Oirecюry.GetDirectoпes(Sa\·esFolderPath): 
for (inl і= О: і < sa,,cF oldersJ_cngtl1: і+-) 
var folderName = sa,1eF o\ders [і] : 
if (!File.Exists(S" {f older 1 а111е } / {Sa,·el1foi\;:1t11e}" )) 
{ 
s 
482.ЧДТУ.231926 -О 11 12-01 
contiпoe; 
save obj = ПLІІl; 
= 
J·s on conve)1 ·t.DeserializeObject<Save>(File• R е а dAl 1T· ext($" {fi. о \d erN  ame} / {S ave!nfo№one}o "b)j)  ; 
catc\1 (Ехсерtіоп е) 
Debнg.LogEпor(e .Message); 
со11tіш.1е; 
yield retшn obj; 
public Т Loatl<T> (string key) 
wl1ere Т: IDataStOl'age 
if (CштentSave == null) 
{ 
tl1row 11ew lпvalidOpe1·ationExceptio11("Cнrre11t save is not setted"); 
vаг saveDataPath = SavesFoldeгPath + $"/ {С штенtSаvе.Nаше} "; 
vai· saveFi]ePatl1 == saveDataPath + $"/ {key} .json"; 
if (!Fi le.Exists( saveFilePat\1)) 
{ 
tl1row new InvalidOperationException($"File at {saveFilePath} is not exists"); 
86 
4И2. Ч)Л'У.23192{)-О І І 12-0 І 28 
.. ~оп == І·Ї \с . 1{ саdЛ І ІТ1.:х І(:;аv1.:І ·ї Іt.:1'·,tli) · 
Viii J~ ' • 
vai.  ,,1 ,,1,., :.: J:ю11Co11v1..:1·t.!)cs~1·ializt:01) 'І''' ' l,;- I • (.1' 1 • • ' . " " • ,• so11 ) ; 
1·еt11п1 data; 
publ ic void Savc<Т> (st1·i11i:; kcy, '\' duta) 
w\1ere Т : 1DataSto1·agc 
if (Cut-rcntSavc == 11ull) 
tJ11·ow псw l11val idOpcratio11Exccplio11("Cuп·c11t savc is 1 0l scttcd"); 
vai·saveDataPat\1 = SavcsFoldc1·Patl1 + $"/ {Cштc11tSuvc . Nн111c } "; 
var saveFilcPatl1 = saveDalaPatl1 + $"/ {kcy}. json"; 
if (! Dігесtогу. Exists(saveDataPatl1)) 
Di1·ectoгy.Crea teD і 1·ссtогу( sav eDataPatl1 ); 
var jsoп = JsonConvert.SerializeObject(dat11); 
File. WгiteA\lТext(savcFi\ePat\1, json); 
} 
І 
Файл IDataStoгage 
namespace Adventшe1·. ModLІles.Pe1·sistent 
public interfacc TDataStorage 
{ 
Ьоо\ Get<T> (stri11g key, out Т data); 
void Set<T> (striпg key, Т clata); 
І 
87 
--
482.ЧДТУ.231926-011 12-01 29 
· . aг,iDataSюrage 
-·, 8111 ; 
0;JІ. 
асе Ad\renrurer.Modules.PersiS[ent 
::~ь-Р 
1 ,.,,0ryPackable] 
~ 1е, .,.. • 
~uьlic parrial class BinaгyDataStorage: IDataSrorage 
І 
l 
private readonly Dicrionary<string, byre О> -data = ne\YQ; 
public ,,oid Set<Т> (string key, Т dara) 
{ 
_d arn (key] = !'.tfemoryPackSerializer.Serialize(d ata); 
\ 
) 
public bool Get<Т> (string key, ош Т dara) 
{ 
if (!_data.TryGetValue(key, out byte О bytes)) 
J 
t 
data = default; 
retum false; 
} 
data = -Memor.v, PackSerializer.Deserialize<Т>(Ьy1es); 
retum true; 
} 
Фай.1 Sa,,e 
llarnespace AdYenturer.Modules.Persistent 
88 
-
-Н(> Ч nт" ,.., 
-· ; -1_ ) , __, \ ()~6-0\І 12-01 
[Si:ri,1Іi zнl>ll:] 
ьІ іс сІа~~ Si1,·~ 
ptl 
, ~\' ІІ ,ІІІІ<.' І Іl'ltl\ \НІ\ ІІL' ~ІІІ\\ !' О 111 \l', 
рт \IL' н: \l!tiнly ~ 11· і в~ , t't·~ioн; 
ІІ,II1\t.' - п:ННL': 
p11bl1"· ~ІПІl!? 'ашL' -> _ 11a111L'; 
pt1blic jtri11g \1~rsioп -> _ ,·~r~iu11; 
ф ~ 
аю lobt)yP1'1yt:r 
tanн::)pacc Лd, t:nturcr. Sc~лc-. Lt>\,P) 
Ptsblic scal ·d сІа ~ Lobb,·Plu)'CГ ·~1" orhB·l1.i'юur 
J 
І 
482,ЧДТУ.231926-01112-01 31 
[ticld: SунсУаг(Іюоk == 11aiнcol'(U p(\11tcRcщ\yVic\1/Statc))] p11bli<: ЬооІ 1 :;Rciнly { gct; 
[Co111111n11d] sct; } . . - . , - , . 
[field: SyпcVai(lюok - iмiнcol(UpdatcO\vнc1·Vic\\'Stнtc))] р11ЬІіс ЬооІ Ca11Sta1·tGш11c { get, 
set; } . 
[ficl(I: Sy11cViн] pt1bl1c СІ1,ю1сtс1· СІшІ'ІІсtс1• { gct; sct·; } 
private Playe1·Pl'Ovide1·<LobbyP\aye1·> _playc1·rl'Oviclci·; 
µгі ,•аtе LobbySer,1ice _lobby; 
pгivnte LobbyVicw _lobbyVie,v; 
(І11ject] 
рнЬІіс void Co11st1·t1ct (LobbySel'\1icc ІоЬЬу, РІнуегРгоvіdег<LоЬЬу РІауе1·> playe1·P1·ovide1·, 
LobbyView lobbyVie,v) 
_lobby = ІоЬЬу; 
_playe1·Provider = playerProvide1·; 
_lobbyView = lobbyView; 
(Сошmапd] 
public void CmdStaгtGame О 
_lobby.ReqL1estStartGa111e(this); 
public oveпidc void OnSta1·tClient О 
UpclateReadyViewState(false, IsReady); 
UpdateOwпeгViewState(false, CaнStai-tGame); 
public ove1тide Yoid OnStartLoca\P\ayer О 
_playeгProvide1·.SetLocal(t\1is); 
90 
-
482.ЧДТУ.231926-011 12-01 32 
pri,,ate \,oid UpdatcReadyVicv-.,State (ЬооІ oldYalt1c, ЬооІ не,vУаІне) 
,,iew.SetReady(newValпe ); 
if (isLocalPlayee) 
_lobbyView.SetReady(newValue) ; 
private void UpdateOwпeгViewState (bool oldValtte, bool пe,vValue) 
_v iew.SetHost(newValнe); 
public sealed class Facto1-y : IGameObjectFactoгy<LobbyPlayer> 
private readoпly UnityFactory<LobbyPlaye1·> _LшityFactory; 
private гeado11ly JObjectResolveг _ objectResolver; 
public Factшy (IObjectResolver objectResolve1·, 
LоЬЬуРІауег prefab, Traпsform paгent) 
_objectResolver = objectResolver; 
_unityFacto -y = new UnityFacto1·y<LobbyP\aye1·>(prefab, рагепt); 
1
рнЬ\іс LobbyPlayeг Prefab ==> _ нnityfactory.Pi·efab; 
public LоЬЬуРІауег Сгеаtе О 
{ 
var instance = _tшityFactOl'y.CI·eate(); 
_o bjectResol ver. І nject( instance ); 
91 
-
-
482.ЧДТУ.231926-011 12-0 І 33 
1-etlІl°П iпstance; 
public voicl DestІ"Oy (LobbyP\aye1· ii,stance) 
_u nityf actoІ"y.DcstІ"oy(iпstaпce ); 
} 
} 
Файл LobbyPlaye1·Spawner 
na111espace Adveпtшer.Scenes.Lobby 
рнЬІіс sealecl class LobbyPlayerSpawнer : 
\ServerSpawne1·<Netwo1-kC01111ectionT0Clieпt, LobbyPlaye1->, 
\Clie11tSpawne1· 
private геаdовlу lGaшeObjectFactoгy<LobbyPlayeг> _facto1y; 
private 1·eadonly LobbySe1-vice _ІоЬЬу; 
private readoпly Dictionai·y<NetworkConnectionToClient, LobbyPlayer> _spawned = ncw(); 
public LobbyPlayerSpawnc1· (IGa111eObjectFactory<LobbyPlayeг> factory, LobbyService 
ІоЬЬу) 
_factoгy = factory; 
_\оЬЬу = ІоЬЬу; . 
} 
Ptiblic GameObject PrefabGameObject => _facto1y.Prefab.gameObjcct; 
РІІЬІіс lEnнmerable<LobbyPlayer> Spa\.vпccIObjects => _spawпed.Values; 
PUblic LоЬЬуРІаусг Spawn (NetwoгkConпectionToClient conn) 
{ 
92 
• 
482.ЧДТУ.231926-ОJ 1 12-01 34 
,,аг player == _factory.Create(); 
_spawned.Add( conn, player); 
\obby.AddPlayer(player); 
Network.Server.AddP\ayerForConnection(conn • р 1a yer.game оь~· ect );  
гett1m рІауег; 
public void Unspawn (LobbyP\ayer instance) 
if (!_spawned.Rcmove(i11stance.co1111ectionT0Client, out LоЬЬуР\ауег player)) 
retuгn; 
_lobby.RemovePlayer(player); 
NetworkScrver.RemoveP\aye1·ForConnection(instance.connectionT0Client, 
p\ayer.gaшeObject) ; 
factory.Destroy(player); 
public GшneObject ClientCгeate (Spav.1nMessage msg) 
var player = _tactory.Create(); 
retшn playeг.gameObject; 
public void ClientDestroy (GameObject obj) 
if (!obj.TryGetCornponent(out LobbyPlayer player)) 
throw 11ew IпvalidOperationExceptioп( 
ь. ·t {оЬі name}. Canпot find {playeг.GetType().FttllName} 
$"Cannot destroy ga111e о ~ес J' 
cornpo 
пent attached to it"); 
_tactory.Destюy(player); 
} 
93 
35 
р1·і,1нk 1·~:нtіонІу Nct\\1oгk Facatlc _11c1,,101·kFacadc; 
p1·i,111tc 1·~:1нІсюІу Pcгsistc111Scг,1 il:c _pc1·sis1c111Sc1·,1icc; 
_ sсе11сС\нюgс1· = sсснсС\11шgс1·; 
11c1,,101·kl-;- iн.: 11tic == 11ct,vo1·kГпcadc; 
pt1blic Task Load() 
і Г L 11cl\\'01·k\=acatk.Co1111cct і оп Туре is 11t1ll) 
tllt·o,v ПС\\' J11,•alii\Opc111tio11Exccptio11("Can110t load ІоЬЬу sccne, 
Со,щесtіонТуре is поt set"); 
1·сt11п1 _sсепсСІшпцс1·.С\ш11gсSсс11с("LоЬЬу"); 
} 
Фа'"н л LobbySeг\re1·State 
U~it\fьl  sy stc111; 
І1sі111, Ad 
ь vc11tшe1·.Coгe.Factorics; 
1.tsi1н, Ad 
с, ''Cнtнгer.Co1·e.N i.::L\o\lO І'k ; 
94 
4Х2. Ч) {ї'У.21І<)2(>-01 1 12-0 І Зб 
. лdvc11tllrcr.Mo(\t1ks.(..:l1ar:н.: 1 1.:п,; 
~s1ng 
jng Mir1·u1·; 
115
pirlJ\ic sca kd class LobbyS1.:rvc1·Stalc : Sci·vcrSІu\i; 
р1·і vutc 1·cu<lo 11 І у Л<.Іv1.:11Іш1.; 1·№:t ,vo,·k І )iscovi;гy _ di~covcry; 
pr·i ,•atc 1·cado11\ у І Si.:rv1.;r·Spa,v111.:1··- №twurk<.:onncctionT0Cli<:пl, U1bbyPlнycr> 
ylaycrSpa ,vocr; 
rri,1a1c rcudoп l y Nct,vork l:,н:a<Jc _rн.:t,voгkГ-:зcudc; 
р11ЬІіс JJol,byScrvcrS1atc( Л <І vc11t11г1.:1·№t work l )is<:uvcгy <.lisi;ovcry, 
ІScrvcrSpa w11cr<Nct \vo,·kС о 11 псе\ іопТоСІ і<:111, СоЬЬуР Інусr> pl~ycrSpuwn<:r, 
NctworkFacadc nctworkF..icadc) 
networkfncudc = пcl\\1orkГ-acadc; 
_discovery = discovcry; 
_playcrSpawncr = pluycrSpawпcr; 
public ovcrridc void 011E11tcr () 
_discovcry.StartServer(); 
public ovc,тidc void On Ex it О 
_d iscovery. St op Di scovery(); 
. kS ' r conncctioпs.Values) 
forcach (var соnп in Nctwor · cr,e · 
f ·Conпcction( солл, true); 
NctworkServcr.RemovePJaycr 01 
95 
482.ЧДТУ.231926-0 1 112-01 37 
'-Ііс o\·etїide Yoid 0 11ClientConnectcd(Net,\·orkCo . Т ci· 
ptІi- пnectюn о 1ent conn ) 
{ 
рнЬІіс O\'CtТid~ Yoid OnClienrRe<1dy (Nen,,orkConнectioпToClient соnп) 
ylaye1·Spa,,.-ner.Spa,\ln(с ом); 
рнt,Ііс o,·erride ,,oid 011ClieшDisconнcc1edlNet\\'OrkConnectionT0Clicnt conn) 
r 
\ 
f'oi-eacll (,1ar lobbyPlayer ін _plnyerSpa\\'ner.Spnм1edObjects) 
it" ( lobbyPlnycг.con11ectioп ToC'licnt = сошl) 
_р !aye1·Spa\\1ner. Uп sра\\111( ІоЬЬу РІауе1·); 
} 
Файл LobbySeг,1 ice 
usiпg Adve11tllгeг,Scc11es, Gn111eplиy: 
11si11g Syste111.Collectio11s.Gc11e1·ic; 
t1siнg Systeш.Liвq; 
11siпg U11ityE11gi11e; 
11a111cspncc Ad\le11tш·c1·.Sccnes, Lobby 
Р\ІЬІіс senled class LobbySe1·,,ice 
І 
.· 
Р1 1vnte rea,lo11\y 'L \ci· scc11cLoa<lcr; 
Ga111epl11ySceнc он< -
І 0 l1 t  ,р\ауегs = І\С\~10; 
Pl'ivnte rendoпly List<LobbyPlayci·> - )) 
96 

4Н2.Ч)(ТУ.23 19211-О І І 12-0 І 39 
І . , sсн Іс,І сІш,s LobbyVicw : Mo11olkliaviщ,r 
р11І1 ІС 
! [Scr·iali1.cl;iclcl] p1·ivat1.: Bt1tto11 _,·сщІуІ3нtІоп; 
[Sci·ialiicFiclcl] p1·ivulc Ut1tlo11 _nо1·1~сщІуІ3u ІІоJ1 ; 
[Sci·ializcFicld) p1·ivatc Пt1Іtо11 _stш-Юam1.:Buщ,,,; 
[Scr·ialiicFicld] рІ'і vatc Butto11 _ scJcctCІшпictc,·But1oп; 
[Sci·ializcFielcl] p1·ivatc Bt1tto11 _kavcHtilloii; 
privatc NctworkFacadc _nctwoJ"kStaJ"tc,·; 
privntc Playe1·P1·ovide1·<LobbyPlaycl'> _playcrPJ"ovidcr; 
[І 11jссІ] 
public voicl Const1·uct (Nctwo1'kFacadc nctworkStaitcr, PlaycrProvider<LobbyPlayer> 
,Іаус1·Рюvіdе1·) 
-11et\voгkStai·tcr = nctwoгkStal'lcг 
' 
_playe1·Pl'Ovide1· = playc1·Pгovidc1·; 
privale void OnEnable О 
_readyBuнon.onClick.AddListc11c1·(St:tLocalPlaye1·Ready); 
_110tRcadyBнtton.onClick.AddListc11e1·(SclLocalPlayerNotReady); 
_sla1·tGaineBвtton.onClick.AcldListenel'(Rec1t1eslStarlGame); 
_lcavcBt1tto11.011CJick.AddListencr(LcavcFl'omLobby); 
} 
pi·ivate void OnDisable () 
{ 
_гeadyBt1tton.onClick.Ren10veListe11e1·(SetLocalPlayei·Ready); 
_11otReadyBt1tton.011CJick.Re111oveListe11e1·(SetLocalPlayeгNotReady); 
_S Іагюа~пеВlt tto11 .011СІ і ck. Rcino vcListcneг(Reque5tStartGame ); 
98 
482. ЧДТУ.23 1926-011 12-0 І 4<) 
ІcaveButto11.011Click.Re111oveLis1c11c1·(1~cavcl7t•omLol>l>y); 
. юі<І SetH.cady (ЬооІ 1·сасІу) 
piJ\)\tC \ 
І 
1 
·cuu,1 yJ3LІtto11.ga111cObjcct. SctЛct ivc( І·  1·сщІу) · 
1 , 
-1101 Rcauy IЗLtl 1011 .gшncObj cct .SctЛct і vc( 1·сщІу ); 
-stai•tG:1111cBL11to11.i11Іc1·ac1at1Іc = 1·сжІу; 
· ,, 1с void SctLoca\PlnycгRcady () 
рГІ\ н 
if (!_plnye1·r1·ovideг.GetLoca l(olll LobbyPluye1• pluyc,-)) 
tliгo"' не,,• І11vа Ііс.Юрсп1tіо11Ех<.:срІіо11("РІ аусг 1ю1 ГоtІn<І") ; 
playc1-.IsRcndy = tn1c; 
priYate void SetLocu\PlaycrNotRcady () 
if (!_playe1·Provider.Ge1Local( oul LobbyPlaycr рІ с:1усг)) 
tlнo,v 11e,v l11 validOpeгatio11Exceptio11("Player nol round"); 
p\aye1·. lsRcady = falsc; 
privatc ,1oitl R t:чucstStar1Ga111c () 
if (!_playerP1·0,1ider.GetLocal( out LobbyPlaycr playcr)) 
thro\v 11e,v IпvalidOperationExceptioп("Player not found"); 
player.CindStartGameQ; 
} 
Private void LeaveFromLobby О => - net~'orkStarter.StopO; 
99 
• І 
І ~ , i;1 JitL·J їc l tl ] рт з1 с Т~1 Р Іс t 11IJ~t'r , ,1111t •. 
i :eпJlttl.'l:,eJJ] rп, з 1 1.' ТМ І)_ Гс;1.t _1,l{t,>JJ~ l't." \І . 
І t>І'l;1 І iil' l-ї t· ld] f1ПУ:11 С Т 1 Р_ Тсх1 _і O\,n •ilc,t. 
І ~rializcJ=-rcld) ргі ,1а 1с stJi1114 _te, t\Vl1c110\, пеr: 
І er·i;1 lil cl7i~Jd] private st1·i11g _te:--1 \\' l11.~ 11RL·Jdy: 
~;1111cObjcc t . 1ш111c = " /L01313\' PLAY[ I{ \ ' lE\\' ] " ~ 11с,,· 1 ,11нс : 
_plзyrr-N aшe. tcxt = 111~. \\1 шнс: 
public ,·oid et Reudy ( ЬооІ не\\\' tlLІc) 
_isReadyTe, t.tt'XI = 11e,v\Іt1 \t1 ' '? _І ~,t\\їt 't1R •Jdy : "": 
rubl1~· \ он.І t·tl-lost ( tюоІ не,, \ ',1\uc) 
100 
482.ЧДТУ.231926-ОІ 1 12-01 42 
І p1. . Dictioнn1y<Ga111eObjcct, lCІientSpa,vпeг> clientSp . _ ()· 
,,11tc _ awners - new , 
ptib\І.C  \, оіс.І AddHanc\leг (IClie11tSpa\v11e1· spawпer) 
{ Ncl\\ІOt·kClie11t.Rcgistc1P1·efab(spawnel'.P1·cfabGaшeObject, 
spa,vne1·.Clie11tCrcate, spawпecClientDestюy); 
clieпtSpaw11e1·s.Add(spaw11ecPrefabGa111eObjcct, spawпei·); 
ptiblic ,,oid Re1110,1cI-Iandlcr (IClientSpav,111eг spawncr) 
Net\\'OгkClicnt.UпгegisteгPгefab(spa,vnc1·.P1·cfabGameObject); 
_clicntSpa\vneгs.Remove(spawner.PretabGaшcObjcct); 
Файл IClieпtSpawnel" 
nш11espace Adventuгer.Core.Factories 
рнЬІіс inteгface IC!ieпtSpawneг 
public Ga111eObject PrefabGaineObject { get; } 
GaineObject ClientCreate (SpawnMessage msg); 
void ClientDestюy (GaineObject obj); 
} 
J 
Фан". rr ISei-verSpawner 
naniespace Adveпturer.Coгe.Factories 
{ 
РUЬІіс interface IServerSpawner<ТArgs, ТТуре> 
{ 
ІЕ11t1111е1·аЬІе<ТТуре> Spaw11edObjects { get; } 
101 
482. ЧДТУ.231926-011 12-01 43 
, S ,:1,,,11 (ТЛ1·~s :щ~s); 
·(ІУР~' І . 
. JІ\\,, 11 (Тlурс 1тт111сс); 
• 1U 11~\ 
\1(1\l 
І 
i ЬІіс Т'Гурс Sp:"''11 () 
j)\I 
1~ttн·11 Spa,,111( I::mpty A1·gs. ll\stш1ce ); 
pttblic s!l'ttct E111pty A1·gs 
pttl>lic static 1·с;жіо11Іу E111ptyA11y, l11sta11cc = 11с\\1(); 
Фаііл Sce11eSpa,;v11eгsRegist1·y 
na111espacc Аd,1с11tшесСоге. т~acto1·ies 
р11ЬІіс class Sce11cSpa,v11e1·sRegistгy : !lпitializable, IDisposable 
ргі,,аtс геаdопІу ClieпtSpa,v11Ha11dlc1·s _c lie11tSpa,v11 Ha11dleгs; 
p1·i\'ate IE11u111eгable<lClie11tSpa,v11e1·> _spa'A111e1·s; 
pt1blic SccпeSpaw11e1'sRegist1-y (1Епшпе1·аЬІе<ІСІіепtSра,v11ег> spa,,111eгs, 
ClicntSp·'1 "'П Н ан d І егs cl1,e нtSpaw11Handleг) 
( 
-sра,,,пегs = sp:нv11e1·s; 
_clieпtSpa,,1111-laшi ka·s = сІ ie11tSp,l\\'nl·!a11cllc1·; 
) 
Pttblic vo 1'd  І . . 
пitinlize () 
{ 
tо,·сасІ1  , .. . 
(V,\/ SJ)fl\.VllCI' 111 _SJ)fl\•V llCГS) 
102 
1 111 
рнЬІі~ sealctl L:lt1ss U11ily l.-!1t.:t 1н·y•c.;.T\Yp •'·: lt l:11Hl:Ol1.k1·1 1 11 1l: l111)' '-' l " І Y1ю • 
,,,11~1·t.: ·пур1.: : i\1t l,1юtkl1:l\1 i1н11· 
{ • • І ' 
' . 
рнЬІіс ТТурс .Рп; І'аЬ t ~1.:1: } • 
pttl)\ic 'РТурс Є1·соtе() 
{ 
Tl'ypc i пslaiii;~ :.:.: u1 1і  tуІJІІ !;\ іІ ,~. Ol,j \;t;I. I1 1s 11111 І iat<;( Р 1·t: l'al), •J Щ 1·~111 J: 
1·etL11'11 •.іт,1ш1сс; 
ІОЗ 
► 
,.. 
45 
рнЬІіс ТТурс Pt·c!i\t) { gct: } 
їТурс C1·catc(): 
voitl \)cs\юy(Tl'ypG i11~t1111ct:): 
pttblic intct·!. .a ce 1l ~nctoгy<oнt ТТурс> 
{ 
ТТурс Ci·catc(); 
Файл Cl1ai·acte1· 
na111cspacc Aclvc11\ttrc1·. Modп lcs. Clш1·actc1·s 
! 
[Sс п.а  1i· zable, MeшoryPacknble] 
public ра(г t·ш  І s,l .r t1ct Cl1ш·acte1-0ata 
( 
І Pt1bl ic В 0<\У   с 01npone11tData Bo,ІyCo(llponentD•t"; 
PІ ttblic sca І ed class C11aracte1·: Netw01-kBcl1avio!lr 
[ficld: se п,·.i \.1_ ze F1.e ld] pt1bl1.c  st11.1 1g Ur11.q t1.1 efti { get,.  s.e.t,  } 
[fie\d: sе ,. .ш  l1.z eF1.e ld] p,·ivate Clш-ncte,·BodyC0111ponc11t BodyCoinpo11ent { get; set; ) 
· e1
[ficld· s .·1 al.1 zcFicld] privatc мovcine11tC0111po11cnt Move(llentC001po11ent { get; sct; } 
104 
,)d) ( ·t>i11po11c11t.SctO::itc1( data. BodyCompoпi:ntD::нa); 
13
•rc~ion . Е Г{ VІ : І< 
pul)lit: ,u1d ~i:tBщiyP:.111 (ВщІуРагtDаtз d,.11a. і 111 slot) 
ІЗоd) t ·0111ро11~1н . Set 13ody Рш1( dзtи. slot ): 
Rpt:ScLl:k,JyraJt(tlatu, slot): 
ic1\11H\H\ пJ] 
pn, JІt' ,l1iJ C111JF~1cl1Dat t1 () 
Rpcl! pJ:нc' D:нщ GctData() ): 
l о_-
47 
, І ~11,v~' t\\1~t~,1·2 1\i1·ct: Іi1) t\) 
\\' \\\\\ 
1\\\І1 \ 
і ,11tl \,1щю\\~\\t . r\1t1,,·~((\i1\'~tiщ1)· 
~ \іІ\\.'\\1 \ ' 
\'  ~ 11,,·ctllt'tІI (\нщ,(111с11t .SctD cst і 1ш tio 11( pos і t і оІ\) ; 
\Clk•11tI~p~] 
pi·i,•,Іt'-' ,,t,i(\ H.p~-s~tBodyP11гt (BotlyPaгt.Datн data, іпt slot) 
І 
\ 
BoLiyC0111poпe11t.SetBodyPш·t( (\atn, slot): 
[C'lkt1tl~pt:] 
pri,,ate Yoict RrcUpdнteDnta (Clш1·acte1·Dнta clata) 
Sct.Data(1 iata): 
#~11dгegio11 
І 
І 
Фзй·n  СІ шшсtе1·Sрюv11ег 
t.lntr~p·•t c t,  •• \d ''c11tшeг.Moclt1lcs.Clнш1cte1·s 
І 
PubJic Rtt 
' 11c, t.  С ІшшсtегSра,\r11Агgs 
1 
І 
106 
48 
рuЬІіС Cl1>1п1CtcrS ра w11er ( І G ,ш,eObjcct Facto1y<Clшп1ctor> сІ1ш·11сtс1·1' 11cto1·y) 
( r"'' tei·fнcю1-y == cl1ai·acte1{'acto1·y; 
С 1Іі І "" 
рuЬІіс !ЕІІ шuera Ь І e<Chш·acter> Sр а 1v11cdO bjccts => _, pn1vt1cd; 
public o ,111100bjcct Pre fabG amcObjecl => _c lш1~c1erF acto1-y. РrеГі1 b.ga111cObjcct; 
рнЬlіс Cl1n1·acteг Spa"vn (Cl111гacterSpa"vvnA1·gs a1·gs) 
_spn\vned.Add( с\1агасtе1') ; 
Net,vo1·kSe1·ve1·.S pawn( cl1aracter.ga111eO bj ес!) ; 
return characte1·; 
І • 
рнЬІіс void Unspa"vп (СІш1·асtе1· c\1a1·acter) 
( 
_spawned.Re111ove( character); 
Netwo1·kScrver. Uп S раwп( chaгacter.gan1eObjcct); 
_chaгacteIFactory.Destroy( cl1a1·acteг); 
І 
Pub1І· с GaineObject ClieпtCreate (Spa,vnMessage insg)  
І 
Var сІ1аr acteг = _c l1ai·acterf acto1·y.С  1·е  а·  te()·'  107 
482.ЧДТУ.231926-0 І І 12-0 І 
Add(cl1a1·acter); 49 
~i1ne d·  
,,s PP i·actc1·.ga111c оь·~ ect; 
,11 с 11а  
retil, 
. 'd Clie11tDestroy (GameObject obj) 
Ь\ІС уОІ 
р~ 
( if (!obj.TryGetC0111ponent(o ut Charactel' instance)) 
t1u·oW ne\,V I11validOpe1·atio11Exception( 
$"Cat1not deS!юy game object {obj.пame}. Cannot fiпd 
GetType().Ful !Nаше} co111ponent attact1cc\ to it")· 
~ance. ' 
І 
_spawпed.Reinove(i 11stance); 
cliaгacterf actoгy. Des troy( instaпce) ; 
$3ЙЛ MoveшentComponent 
!ЗJJ\espace Aclventшe1·.Modules.C\1aracters 
public class Moveme11tCompo11e11t : MonoBehavioш 
[Serializef ield] pгivate Na, ,Mesl1Agent _age11t; 
public void Move (Vector2 direction) 
{ . 
_agent.Move(new VectoгЗ(dj1·ectio11 .x, О, direction.y)); 
І 
Pllblic void SetDestination (Vector2 position) 
{ 
-agent.S etDesti па ti on(posi tіоп ); 
) 
~aliJi cь 
aracterBodyComponent 
l OR 
-
50 
. , l\;(t:IНOt·yPackable] 
11
. [•І ' І І І z•• ' (; . 
.~-' · ·r··il sh'ttct BodyCoшpoнe11tData 
. p·ll І, · 
~н1,· . 
і . 61L1,,PaitData [] BodyPaгtsData · 
1.\1~· \ ., , 
!'\ll' 
. [S~ria\izefield] ргі\'аtе BodyPaгt [] - datas = пе\,, BodyPaгt [(int)BodySlot.Total]; 
рнЬІіс BodyCoшponentData GetData О 
І 
\ 
,ж datas = пе\V BodyPaгtData Ld atas.Length]; 
tor (in1 і = О; і < datas.Lengrl1; і++) 
datas [і]= _datas [i].GetData(); 
reшm ne\\1() 
BodyPaгtsData = datas 
};  
public ' 'oid SetData (BodyCoinponentData data) 
І 
for (int і= О; і < data.BodyPмtsData.Lengt\1 && і <_d atas.Leпgtl1; і++) 
І 
-datas [i ].SetData( data.BodyPaгtsData [і]); 
} 
} 
Pub!ic . 
vo,d SetBodyPaгt (ВodyPartData В d Slot s\ot) 
data, 0 У 
109 
► 
482.ЧДТУ.231926-0\ 1 12-01 51 
І dyPart( data, (int)slot); 
5,1130 
ь1іс void SetBodyPaгt (BodyPattData data, int slot) 
pU 
І if (s\ot ;:;,== _ datas.Length) 
return; 
datas [s\or].SetData(data); 
for (int і == О; і < _ datas.Lengt\1; і++) 
_d atas [і] .Dispose(); 
їm BodyPart 
gColor = Adve11tu1·er.Modules.Persistent.Unity.Color; 
ІеSрасе Adventurer.Modules.Characte1·s 
sen .a  1i·z able, MemoryPackable] 
Jbl'ic  part·ia l struct BodyPartData 
РuЬІіс Color Color-
' 
Mlics1r·in g AssetGнid; 
Se n·а ІіzаЬІе] 
4ЬІіс clas s BodyPart : IDisposable 11 О 
~----------' ­
482.ЧДТУ.231926-011 12-01 52 
· сf.І С  Jd] pгivatc Ski11nedMcs\1 Rc11clcrc1• гсщ\с 
І - І.С.І.,  
1s~ri·,а ІІZ . . Jd] pi·ivate BodyPartAssctRc{' ~cttiiios• 
.fJC - ::,•' 
1scri3І  ф; 
partData GetDnta () => ne,v() 
ь1іс во dУ  
pU 
( с\\' Co l o1·Lrc11 t\cгcl'. ІПa t c1· i a l .co lo1·) 
101· "' 11 ' 
С 0 ·(\ ::: s~, ШІ.1 !,;,",•·J  · А .",".,~ ' tC.І' U ID '•>')І •  "" 
лss~t G1 1 -
І· 
І' 
. 5\,11с ,,oid SctData (8o(iyP:11·1Data clata) 
publtc з 1 
І 
\ ,ai t SetSettiпgs( пе,v 13odyP:нtAssctf{c l~ dat:1.AssetG ui(\}); 
311
seiColor(d ata.Colo1·.To U11ity() ); 
public async Task SetSettiпgs (BodyPai·tAssct l~ef· seltings) 
-scttinцs?. Uпload( ); ~ 
_scttings = sctt i11gs; 
var settingsAsset = await setti11gs.TryLoadAsy11c(); 
_rendcrer.sl1c1redMesh = settingsAsset.Mesl1; 
_rendcrcr.material = settingsAsset.Material; 
І 
public void SetColor (UnityEngine .Coloг color) 
І 
_reпcteгer.material .color = color; 
PUblic vo.id  Dispose () 
І 
_SC\\j)J!н• ') U
ь·'· · n  Jo ad(); 
111 
~,•;\\\ \\ ,,. 
11\~ ' 
11\. ,,,•,  ,' І'·'" 11~1· : 
І 
• •1, l ·11:11 ;11.:1~•1 
1~1'·1 11 
' ' ~ 
,р.ї'' 1н·1· 
І І 1·1-:1.11~t~,,,н __ ,,а,~•Н: 
: ,._. .,  1'11 ~ . 
: ·:i,\,111\~ її.111s1~,11н І) sp:t\\ 11 \\,і,11:,; : 
1 
I1\.'ІІt = pat~\\l; 
І:І\\ІІРоі111:,; ._., ::ra,,·11PL,it1ts: 
Iehat ,t(' І~г = G.ш,~Ot)_j~rt . l 11st:шt iat~( 1'1 -1':i\,. 
І І' І І ·•О :-\':І\\'\\\\1і111~ . 1 t·11~11l1)] .p,,-:111,111, 
. ~pa\\1t1Pt,i11ts rL)11i1~ 1 :11~•.і11~. \{ :І\\\І\І\\1 - ,;ІІ ~ ' . 
ІП idщ" щ·у , . р:11\.' ІІ\); 
І І • 
-
482.ЧДТУ.231926-011 12-ОІ 54 
ri,,, (Clшmcter instancc) 
'd unsp, 11 
, • \'(11 
.1ь11 
І' 
d Rel110 ,,e(instance ); 
fl\\'tlt: · 
}Р . ci· Ui1Spa\\111(i11staпce.gamcObject)· 
, • ,,,or kSet'' . . ' 
1
~~ ·ccr oestгoy(insiance.gaшeObjecr); 
G9n1cObJ . 
Object ClicntCrcate (Spa\\111Mcssage 111sg) 
ьІіс Gat11C 
~ 
І 
1 
,•n1· 111 1ra сr\~; г == Ga111eObject.lпstaпtiatelp1·efab, 111sg.positio11 , Quaternion •i deпtity'  _pareпt)· с , 
~іlІПІ clщracter:gameObject; 
pJblic yoid ClieпtDestroy (GatneObject· obj) 
il'(!obj. TryGetComponent( онt СІшrасtсг іпstансе) ) 
1І1ro1v 11е\\1 InvalidOperationExceptioп( 
$"Сашюt dcstгoy gшпе object {obj.na111e}. Сапtюr fi nct 
:wice.Ge1TypeQ.Ft1l1Na111e} .compoпent attacl1cd to it"); 
Ga111e0bjcct. Desh·oy( obj); 
І 
\, 
·~1G aшeplaySceheLoader 
~расе AdventLІгe1·.Sce11es.Ga111eplay 
~uЬІіс сІа~ G . 
'· s arnepla.y SceneLoader 
І 
Pri,,aic і·,. 'І . . 
. 1::,ic only Peгsiste11tSe1-Yicc _peгsiste11tSe1Y1ce; 
P~vate ге d 
а опІу ]SceneClшnger _sccneChaпger; 
11 З 
:o І ,,vc l Si.: 1 vit:1.: 
ttіІІІС л1 І v1·11111 1 i:1. S t·i:111:•, .I і ІІІ, 11; рІ 11 у 
/l11jc,1/ р1 iv111i: І Si:1v 1.:1S J)il \V /11:1 ( ' /1111i r<.: lt:1 • i:11 i:111ySpa\v11i:r: 
rщ,1 11: У і~: І1ІІ11Ф11 1: Іі1111 wait'I і 111(; 11t:\\' \\1:,11 / · 111 ~н:ст11І,( І 01); 
11 4 
~ 8 . ЧЛТ .23 l 926-0 l l l 2-0 t 56 
11Оt1ІІІ •1 ltl 1РІ :1у ' 1' 
\ 't' ,\\\\'t'\\І\ІІ'\: І', ' ' t:l\~S. Jtl\\1Cp lнy 
;'4 
fПІ'іІІt' Coi1t1·t)I 1\нр c011tп)\r,.1\ ap; 
ІІісkІ: y11i.:\la1·J ptll>li · Ішпн;tс1· Іш1·асtс1· { gct; sct;} 
fіІЬІіс СІн1111 ·ti.:1· т~н·g 'І { gcl; sct; } 
r,iblico,•c1тidc ,юісІ Он t:н·tLocн\Playc1· () 
D~\щ~.Log(" t rн·t local playc1·"); 
_сонtтоІМар =- пс,v(); 
_со111rоІМнр. Єпн\) Іс() ; 
_co11trolMnp.Mai 11 .Ligt1lAttack.pcJ'Гo1111cd += OпAtlack; 
_coпtюl't\1\ ap.Maiп . \ l cavyAt1ack .pc1-Гo1111cd += OпBlock; 
J 
Pri11n1c vo1· ct 011 Dcstтoy () 
І 
·І rl c0t1trolMнp != ІНtlІ) 
І 
,COІІI L'olMnp.Maiп.LightAttack.peгfoлнcd -= OвAttack; 
,coщюtMar.Main. l lcavyAttack.pc1-Гot'І11cd -=О пВ Іосk; 
11 5 
-
482. ЧДТУ.231926-011 12-0 І 57 
( 11 ('' nu\ \")',  
ре ьІ Jg . L 0о 
rctt1!1І ; 
.,, - coнt1·0ІMap .Mai11 .Movcme11t.Rec1dValt1e<Vector2>()· 
2-- ' 
if( !v2.єqна \s(Yecto1'2-zero)) 
Dcbug.Log(v2); 
Characteг.Move( v2); 
rnva1ev oid OnAttack (CallbackC011text iнput) 
\ · . 
if(!Chaп1cter) 
rctt1111; 
Character.Attack(Tai·get); 
І 
p1iva1e v0 1·d On B\ock (CallbackContext .in ptit) 
 
\ 
іf(І· СІ1 aracte1') 
ren,n 11 6 
1. 
' 
58 
\:i:'ttt<SH\l\l~ ;:; _\Іпіtу Fac.tot')'.Ct·catc(): 
_,,bj,~tR '$l)l\·~r. l11j~ctt iпstнnc~ ); 
~іUШ ІН~tщ 11..' •: 
_ll !lityf ,к'tory. Destroy( і11stппсе ); 
~ :!illep\ ау р lауеrSрюл'11ег 
-~.\dv~t\l 
u.rer.Scenes.Gnrпeplay 
117 
482.ЧДТУ.231926-01 l 12_01 
59 
pІayerSpa,vner : 
? 0:н11ерІ,_зУ . -r с1 · 
~r<• ,1.с г ,vorkConnect1011 •о  1епt ' GащерІауРІ ayer>, 
,rSP:1'1rt1 
· ,,,er 
,i5p11'' ,, 
G: eplayPlayer.Facto1y _Гасtогу; 
1111
(.tdo11IY . 
tlr d nl)' ptayci·Prov1dcr-<Ga111cplayPlayc1·> _playci·Pi·ovidci·· 
(\'.І о . ' 
~t.l  -,,te re:i don lY Dict1onary<Nct\vorkConncctio11ToClicl\t ' Ga ~пер Iа у р layer> spawned = 
-
public Ga111cplayPlayc1·Spt1,vncr (G атер І ayJ>layer.Factory factory, 
eplayPlaycr> playc1·Pю,1 idcr) 
1ide~G a i1 1
~ciorY == facюry; 
Providcr = рІаусгРгоvіdсг; 
муеr 
\с 1Enuroerable<GameplayPlaye1·> Spa,vnedObjects => _spa,v11ed .\'alнes; 
hcGame0bject PrefabGamcObjcct => Jac101y.Prcfab.gameObject; 
Ік GameplayPlayer Spa,vn (Net,vorkC01111ectionT0Clie11t args) 
ирІауеr = _factory.Create(); 
їp31v11ed.Add( aгgs, ріа yer); 
~ug.Log("Created object"); 
lt11\"orkServer.A c!dPla yerForCon песt і оп (R r gs, р layer.garпeObject ); 
~bug.Log("Replace playcr"); 
::Urn player; 
l:•yoid Un 
spawn (GaшeplayPlayer іпstапсе) 
((·' ,Spawned І< . . . G meplayPlayer рІауег)) 
· einovc(instance.connect10nToCl1eпt, out а 
1І  8 
4g2.-ЧДТУ.231926-0I1 12_01 
60 
і ,_. .. е twoi·kServcr.RcinovcP\ayerForCon І nectю. n(insta ncc .c on nect.ю nToC\1' ещ, 
1 
. C\ieпtCreate (Spa-.vпMessage 111sg) 
1 
"GJflleObic 
,' 
yьrerProvidcr.SetLocal(playe1-); 
:JJ11Piayer.gan1eObject; 
:1void ClientDestroy (GaineObject obj) 
:(!ooj.ТryGetCompoпent(out Gar11ep\ayPlc1yer player)) 
~JoІv new InvalidOperationException( 
S"Cannot dcstroy game object {obj.name}. Cannot find {p\ayer.GetTypeQ.Ful\Name} 
- ~1a1tacl1ed to it"); 
.f щогу. D estroy(p1ayer); 
119 

... ,. . .,. . .. -~ 
- - • :- ,,.~ - i 
. ,, 
,,,':;:;;--:.1.;· 
Pv.c. В. 
rотовності. Діtя -roro шоб змінити свій с--rан на ·таrовш'Г потрібно натиснути 
1шоrrку '~R.eady". Ддя ·roro щоб обрати персонажа потрібно натиснути кноп:~-..·у 
нSclcct Character'. 
В меню персона:мJВ м<r.,кна обрати 0,1.Ноrо 1з 1снуючих, або створити 
lfUІIOI'O . 
121 
Рис. В.2 - Меню лобі 
rpl1 на екран~. з ' являються 1шошш керування персонажем. 
nicJI!! 110q.a 1'1..{ Y сторони екрану відповідає за п.ереміщснням персонажа. 
i tJ( З .. ·J JIJ301 -• сторони - за його поворот. Кнопка з правої сторони 
11
·f 1~ з · І1Рав 0у1 і~пuІІХ персонажів. Цифри та червоний. індикатор показує 
11
<І araI< 
:~~а є з" , nерсонюка гравця. 
~е здоро!3 я 
.І 
Pnc. В.З -Меню керування nерсонюкем 
122 
---
., 
•І І 
І • 
1 і ' 
• І І 
482. ЧДТУ.23J926_01 І 9О-о 1 
Рис. Г. І - Слайд вступу 
ра·е·.к тrв·~ • нН-я;  ;·_ а Р_о зробка_ _к  о_о пера_т ивного Мобільного ігрового додатку на 
~нов~-u~1~У: _ 
фо·т а BU:l(·O H у,_ва.лась з nикористапшrм технологШ об'скшо та компоненпю 
р:.є нтов аноrо прш:рамування . · 
Рис. Г.2 - Слайд ~пису мети 
• • V 124 
........ ., 
482.ЧДТУ.231926-О 11 90_ І 
0 
з 
Ust:-casc дін~ ·рама І<<)р~,с· , . 
увач ,u 
С11стощ nобі 
r 
.QJ  ; ,✓~,, ,,.--
/\ - - - . \ n..:?.-•)(,u,,j•:~;,.) l'fJ' ·"••'"·· •'.• .• "· • (:- -~r,•·~-· ·:~~,.--· 
r::<.· , . •· 
1 · •. .,  . ... ~ .. 
.::t,l( t1J,.I~ І • ...... . .,,,,.-- .., ,:-J. ... . 
. ·--(~---~--· ·· 
Рис. Г.3 - Слайд Use-case діаграми 
Рсзут,тат 1 1росктуваш1я побі 
І. ...· = 
- --<> :,..--;:~. ::--~.:·::. - ·iJ 
·-~~ •.~... ,,..(>1.,,~. ,,~, ,7'( 
. 14.,_. ....... ., \°'W...,y,f' ( a( 
...'.u r..~1«. 
І : ;};~'t1., 
.~........ ., -. .·-.-.-,  І 
. ,......:w~(.,6~ . .. J І 
-І -t-, •~., ••• ; --... t-..... • 
-- - - .. 
Рис. Г.4 - Слайд діаграми класш 
125 
• 
4Н2.ЧДТУ.23 1926-О І t 9О-О І 
4 
- • • t~,,III1u11f1 11~ • 
---\~t11І~l  1
f~,r1,11 1t f°llt)ffUU І C' С'!!~ " ~---·--
5 
Рис. Г.5 - Слайд "Діаграма мережевих повідомлень" 
..., , 
Рис. Г.6 - Вступнииv  слаиv д в розд•т  "Техrюлоп1 
126 
І 
r 
.# 
5 
Рис. Г. 7 - Слайд використаної тех~~оло ... ''U . 
,. rн шtу та С#" 
МіtТОГ 
Мі!Т()І' iic мережева бібліотека щв1 U11i1y, н 1<а має нбуJющ11-1и і1 фуmщіон аJ ~ J{JІ н 
стнорсння l{PC(l{cmote pюcctltirc саІ \), Oata sупс механізмів. 
Вон~ працює ,ш основі прtпокол ін UПР\ТСР. Та мас 11Jщс11у щщбущщу 11м н11м11 
11ротоколами КСР. 
- . .. оrії " мш. оr"  Рис. Г.8 Слайд використано1 технол 
127 
-
(] 
tio11 ont a,·n  г, V ~onraшcr 
J 'Г - J1C IШIПeJiІfi:J) iiJ;щj .1ІJ/ІІЩ.J/ 
( 1, nti111 i; ( ІІІ f'i'\t 1•. п.1fІІ 
рІ Jl('. J>ІI . JJJІCi.lllt ІЮд ЯІОІ/1 G~ ·~ \((1,1:_..11,1щ l \"''ІІІ( 
_ ,, 1u11, , 
;1,•J L'nitн:c,10. 
(.";JJJIIЯ 
м111• 
І -1, i<:JJ\t Gі6:1 іо1~1ц \ "( ,,m.1m~r ;ii:;j, ю 
JІІІ l,ЛІ, , " ІІІІ, ІІР,.ІJ~J,;ГіtІSІІ ІЮ 11, J 111111111 11 І 
, J)I ко11 11..'1111t:ращ1 . 
11111JltMII 
Рис. Г.9 - Слайд використаної технології ''VContaincr" 
Рис. Г. І О - Вступний слайд в р0Jді11 .. р . ітектура ПЗ'' 
І:! 
482.ЧДТУ.231926-0 \ l 90-О l 7 
епt oi-ieпted pгooтat11t11it1a) 
(со111 р011 о о 
~р Ельtу 
СОМООІІІМІ 
• CDmPO"ltnC• 
con,10111ntl 
•<em~on,111• н--_1 
Ccn-p-"'tnl) 
•ca1npew,ent· 
Сt"1ІК"ОІІІІ 
•ccм,o,,tr,\• 
Рис. Г.11 - Слайд використаної архітектури 
Рис. Г.12 - Вступний слайд в розділ "Інтерфейс" 
129 
L 
482 .ЧДТУ.231926-0 І І 90-О І -
Головне меню 
Рис. Г.13 - Слаі1д 'Толоuнс меню" 
Мен10 лобі та створення персонажа 
14 
р ис . г..]  4 - с лаиv д "Меню лобі та створення персонажа" 
130 
-
482.Ч-ДТУ. 2j 1926-011 C)().Q І 9 
висновок 
результат\ роботи було створено: 
6 
мобільни• й кросnлатформе~~ииv  додаток 
можлив1сть грати разом по покальній мережі 
· Pi~c. Г.15 - Слайд висновку 
дякую за увагу~ 
Студент 4-го курсу, групи ПЗ-1904 Чуплий М. А . 
Вю<0нав: Псрвунінсь1шй С.:. М . 
Керівник: 
16 
Рис. Г.16 - Слайд "Дякую за увагу!" 
131