Professional Documents
Culture Documents
Вачнадзе А М О Бакалавр ІКС 2020
Вачнадзе А М О Бакалавр ІКС 2020
Допущено до захисту
Завідувач кафедри
к.е.н., доцент Базилевич В.М.
Виконавець:
студент гр. КІ–161
Вачнадзе Анна-Марія Олександрівна
(підпис)
Керівник:
професор
–––––––––––––––––––––––––––––
д.т.н., професор
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
Чернігів 2020
2
ЗАТВЕРДЖУЮ:
Зав. кафедри
к.е.н., доцент Базилевич В.М.
“____” ___________2020г.
ІНДИВІДУАЛЬНЕ ЗАВДАННЯ
НА ВИПУСКНУ КВАЛІФІКАЦІЙНУ РОБОТУ
ЗДОБУВАЧА ВИЩОЇ ОСВІТИ
ЗА ОСВІТНЬО-ПРОФЕСІЙНОЮ ПРОГРАМОЮ БАКАЛАВРА
4. Календарний план
№ Назва етапів роботи Термін виконання Примітки
1 Визначення з керівником 27.01.2020
2 Визначитися з темою роботи 20.01.2020
3 Індивідуальне завдання 3.02.2020
4 Знайомство з проблемою,
інформаційними джерелами, аналіз 20.03.2020
існуючих рішень.
5 Прийняття рішень стосовно основних
10.04.2020
моментів розробки
6 Звіт з першої частини роботи (ІЗ, Вступ
24.04.2020 Звіт
та аналіз задачі)
7 Збори з питань практики 08.05.2020
8 Розробка системи 15.05.2020
9 Звіт з практики, розділ розробка 17.05.2020 Звіт
10 Реалізація системи 24.05.2020
11 Попередній захист 29.05.2020
12 Перевірка на «плагіат» 12.06.2020
13 Рецензування роботи 12.06.2020
14 Захист кваліфікаційної роботи 16.06.2020
Завдання підготував:
керівник Зайцев Сергій Васильович
(підпис)
«___» _________ 2020 р.
Завдання одержав:
студент Вачнадзе Анна-Марія Олександрівна
(підпис)
«___» _________ 2020 р.
4
РЕФЕРАТ
THE ABSTRACT
The topic of the qualification work is development of FPS game on the Unity
game engine.
The object of research is the process of creating a game on a free game engine.
The subject of the study is a game for the Windows operating system. The game
was developed by using Unity game engine, which runs on platforms such as Windows,
Linux, MacOS. Unity is a convenient and practical tool for developing computer and
mobile games, etc. In addition, it has become a popular tool among the film and
automotive industries.
The purpose of the study:
- introduction to the tool for developing computer, mobile and other Unity
applications;
- development of a desktop game for the Windows operating system;
- demonstrate the capabilities and availability of the Unity game engine.
Over the last 20 years, the gaming industry has become quite large, influential
and financially profitable. The number of devices that can run games has increased:
computers, laptops, smartphones, tablets, regular and portable game consoles. Over
time, various game engines became available, thanks to which anyone could create
games on their own, as previously developers had to create their own tools for creating
games. Among such engines was Unity, with the help of which this qualifying work
was created.
ЗМІСТ
ВСТУП.................................................................................................................10
1 АНАЛІЗ ІГОР...................................................................................................11
2 ПРОЕКТУВАННЯ ГРИ................................................................................31
7
3 РОЗРОБКА ГРИ.............................................................................................50
3.1.3 AmmoPickup.cs...............................................................................50
3.1.4 AmmoPickupSMG.cs......................................................................50
3.1.5 BarrelBang.cs..................................................................................50
3.1.6 BarrelBlow.cs..................................................................................50
3.1.7 CaveDoor.cs....................................................................................51
3.1.8 CaveDoorExit.cs..............................................................................51
3.1.9 CreackyDoorOpen.cs.......................................................................51
3.1.10 CredToMenu.cs...............................................................................51
3.1.11 CrossAnimate.cs..............................................................................51
3.1.12 CutScene01.cs.................................................................................51
3.1.13 EnemyScript.cs................................................................................51
3.1.14 EnemyScriptSpider.cs.....................................................................52
3.1.15 GameOverToMenu.cs.....................................................................52
3.1.16 GlobalAmmo.cs...............................................................................52
3.1.17 GlobalHealth.cs...............................................................................52
3.1.18 GlobalScore.cs.................................................................................52
3.1.19 GunFire.cs.......................................................................................52
3.1.20 GunFireSMG.cs...............................................................................53
3.1.21 HandGunDamage.cs........................................................................53
3.1.22 HandGunReload.cs..........................................................................53
3.1.23 HealthMonitor.cs.............................................................................53
3.1.24 MainMenuOptions.cs......................................................................53
3.1.25 OpenDoor001.cs..............................................................................53
3.1.26 PauseGame.cs..................................................................................54
3.1.27 PickUp9mm.cs.................................................................................54
3.1.28 PickUpSMG.cs................................................................................54
3.1.29 PlayerCasting.cs..............................................................................54
3.1.30 RespawnLevel.cs.............................................................................54
3.1.31 SkyRotation.cs.................................................................................54
3.1.32 SMGReload.cs.................................................................................55
9
3.1.33 SniperScopeActive.cs......................................................................55
3.1.34 SpiderFollow.cs...............................................................................55
3.1.35 SpiderScore.cs.................................................................................55
3.1.36 SplashToMenu.cs............................................................................55
3.1.37 WeaponSwitch.cs............................................................................55
3.1.38 ZombieFollow.cs.............................................................................56
3.1.39 ZombieScore.cs...............................................................................56
3.1.40 ZScore25.cs.....................................................................................56
3.1.41 ZScore50.cs.....................................................................................56
3.1.42 ZScore100.cs...................................................................................56
3.2 РЕАЛІЗАЦІЯ ДИЗАЙНУ РІВНІВ..................................................................56
3.3 РЕАЛІЗАЦІЯ ІНТЕРФЕЙСУ КОРИСТУВАЧА................................................59
3.3.1 Головний інтерфейс......................................................................59
3.3.2 Меню паузи....................................................................................62
3.3.3 Головне меню.................................................................................63
3.4 ВИСНОВКИ...............................................................................................65
ВИСНОВКИ.........................................................................................................66
ДОДАТКИ............................................................................................................70
ДОДАТОК А........................................................................................................72
10
ВСТУП
1 АНАЛІЗ ІГОР
Гра може містити собі як один так і ознаки кількох жанрів. Незважаючи на
це, існує чітка класифікація жанрів відеоігор [1]. Нижче наведені лише основні.
Рисунок 1.3 – Приклад action-adventure гри (Star Wars Jedi: Fallen Order)
14
Частіше цей жанр називають просто RPG. Гравець контролює дії одного
або кількох персонажів. Механіки та терміни цього жанру перекочували з
настільних рольових ігор по типу Dungeons & Dragons. Персонажі зростають у
силі та здібностях, які розробляє гравець. Рольова гра рідко кидає виклик фізичній
координації гравця або часу реакції. Ігри покладаються на добре розвинену
історію та навколишній світ. Рольові відеоігри зазвичай намагаються
запропонувати більш складні та динамічні взаємодії з персонажами, ніж ті, що є в
інших жанрах відеоігор. Зазвичай це передбачає додатковий фокус на штучному
інтелекті та сценарії поведінки персонажів, що не керуються комп'ютером,
керованими комп'ютером [5].
Деякі субжанри: рольовий бойовик (action RPG), рольова пісочниця
(sandbox RPG), масова багатокористувацька онлайнова рольова гра (Massively
multiplayer online role-playing games, MMORPG).
Приклади ігор: Diablo, Minecraft, Lineage II (Рисунок 1.4).
15
Рисунок 1.6 – Приклад strategy гри (Heroes of Might and Magic III)
Як у випадку з жанрами, гра може мати кілька режимів гри. Можна грати як
поодинці, так и з декількома людьми.
1.2.1.1 Означення
Шутер від першої особи можуть бути структурно складені з рівнів, або
використовувати техніку суцільної розповіді, в якій гра ніколи не залишає
перспективи від першої особи. Інші містять великі середовища з пісочницею, які
не поділяються на рівні і можуть вільно досліджуватися. У шутерів від першої
особи герої взаємодіють із оточуючим середовищем в різній мірі, від основ, таких
як використання дверей, до вирішення задач на основі різноманітних
інтерактивних об'єктів. В деяких іграх гравець може завдати шкоди
навколишньому середовищу різною мірою. Наприклад використання бочок, що
містять вибухонебезпечний матеріал, в який гравець може вистрілити і тим самим
22
Рисунок 1.8 – Приклад ілюзії різних висот при бінарному розбитті простору
Система освітлення ґрунтувалася безпосередньо на коригуванні кольорової
палітри поверхонь: замість того, щоб обчислювати, як світло переміщалося від
джерел світла до поверхонь, використовуючи трасування променів, гра обчислює
"рівень світла" невеликого відрізка рівня виходячи з його відстані від світла
джерела. Потім воно змінює кольорову палітру поверхневих текстур цього
розділу, щоб імітувати, як темно це буде виглядати [16].
Гра була створена з рівнів, група яких разом називалися епізодами.
Фінальний рівень був босфайтом з дуже сильним ворогом. Самі вороги були 2D
спрайтами. На рівнях вони нападали групами. Окрім ворогів небезпечними були
елементи рівнів, такі як токсичні відходи, стеля, яка могла падати. По всіх рівнях
була зброя, патрони, броня, аптечки, ключові предмети, без яких не було
можливості просуватися далі. Також були бустери, які тимчасово давали різні
ефекти, від швидкості до режиму «берсерка».
Окрім режиму одиночної гри, було два режими мультиплеєру –
кооперативний на 4 гравця в локальній мережі, коли можна було пройти гру
разом та “deathmatch”, в якому 4 гравці билися один проти одного.
Сюжет, який був на той час простим для розуміння, розповідав про
безіменного піхотинця (в серії його називають Doomguy, Doom Marine і
віднедавна Doom Slayer), який намагається вижити під час вторгнення демонів
24
Перша частина побачила світ у 2007 році. Компанія “Crytek” була на той час
відома як розробник першої частини Far Cry та ігровим рушієм CryEngine. В новій
грі було показано переваги CryEngine 2, для якого і було створено Crysis.
Розробники намагалися показати неперевершену графіку, що, нажаль, означало
неможливість запустити гру на більшості комп’ютерах того часу. Глибина
різкості, м’які частинки, об’ємне світло (Рисунок 1.10), симуляція води на візорі –
все це потребувало ресурсів [17].
освітлення сусідні ділянки (стики між цеглою, стінами, глибокі впадини і виступи
на поверхні, тощо).
Характерна риса SSAO - це розрахунок ambient occlusion у екранних
координатах (screen space), що робить метод придатним для роботи з
зображенням тривимірної сцени у реальному часі, в певній мірі як пост-обробки.
Класичний підхід базується на буфері глибини сцени, який часто генерують
попередньо, ще до остаточного розрахунку освітлення. Знаючи глибину кожного
фрагмента (пікселя) - можна з певною точністю розрахувати наскільки сусідні
фрагменти затінюють його від навколишнього світла (Рисунок 1.11) [18].
Рисунок 1.11 – Приклад сцени без SSAO та з SSAO (на прикладі Half-Life
2)
Гравець міг бути частиною світу. Замість того щоб дивитися сцену, він міг
пересуватися в місцевості, в той час як історія розгорталася навколо персонажа. У
поєднанні з перспективою від першого обличчя, гравці мали відчуття присутності
в подіях.
До Half-Life дизайн рівнів в багатьох FPS ігор був схожий на дизайн в
аркадних іграх. Потрібно було пройти рівень для доступу до наступного. Рідко
29
коли переміщення між ними було логічним. Тому ігри минулого рідко
переймалися реалізмом, фокус був на геймплеї.
У Half-Life розробники намагалися створити реалістичний світ, який
можливо було досліджувати. Переміщення між рінями було логічним, воно
поєднувало оточуюче середовище з історією. Завантаження нового рівня було
непомітним, його видавало лише назва нової глави на екрані або зупинка гри на
кілька секунд та надпис “Loading…”. Світ гри був ніби без швів [19] (Рисунок
1.14).
певних приміщень або підлікувати головного героя, якщо він отримає тяжке
поранення. Усе це робило світ гри біль живим та правдоподібним [19].
Сюжет розповідав про аварію в науковому комплексі «Чорна Меза», яка
відбулася у наслідок вибуху кристалу із транзитного світу Зен. З цього моменту
головний герой, Гордон Фрімен, намагається врятувати себе і разом з тим
зачинити портал, який підтримується невідомою істотою на іншій стороні
порталу.
Ворогами для гравця будуть як і прибульці, так і звичайні солдати зі
спецпідрозділами, завданням яких є винищення будь-яких ознак інциденту, у
тому числі знищення персоналу «Чорної Мези».
Half-Life 2 була не менш проривною для ігрової індустрії. Раніше будь-який
об’єкт був нерухомим, або рухався за скриптом. Valve запровадила можливість
взаємодії з будь-яким елементом середовища – від звичайної банки води до лез
циркулярної пили та машинами (Рисунок 1.15).
2 ПРОЕКТУВАННЯ ГРИ
Перший крок в розробці власної гри – це вибір ігрового рушія на якому вона
буде створена. Вибір може залежати від будь-якого фактору, чи це потужність
комп’ютера на якому буде розробка проекту, чи це власні вподобання розробника,
наприклад зручність інтерфейсу програми чи мова програмування. Нижче буде
наведено популярні ігрові рушії з яких можна почати роботу новачку у сфері
створення відеоігор.
2.1.1.1 Unity
Вперше був представлений в шутері від першої особи Unreal у 1998 році
(Рисунок 2.2). Створений засновником Epic Games Тімом Суіні. Дeякі технології
були новинкою для того часу, наприклад використанні динамічного графу сцени –
структури даних, які використовуються у векторних графічних редакторах та
комп’ютерних іграх [22]. Ця технологія дозволяє: частково чи повністю
дзеркальні поверхні, варпінг – можливість при прорисовці заміняти зображення
однієї поверхні проекцією зображення на іншу, паралельну їй поверхню та
скайбокс – проектування на поверхні відтворення з іншої точки. Рушій також став
одним з перших, в яких з’явився ефект гало навколо джерел світла, які плавно
згасали, будучи перекриті краями стін по мірі руху гравця [23].
36
2.1.1.3 CryEngine
Продукт компанії Crytek. Усі ігри на його основі мали вставку “Cry” –
Crysis, Far Cry. Перша версія рушія вийшла у 2002 році. Спочатку розроблений як
демонстрація технологій для Nvidia, і коли компанія побачила свій потенціал,
вона перетворилася на гру. Коли були випущені відеокарти з підтримкою 3.0
піксельних і вершинних шейдерів, Crytek випустила версію рушія 1.2, яка
39
Порівняння буде доволі простим але зрозумілим для тих, хто бажає почати
роботу з нижченаведеними ігровими рушіями, але не знає чи зможе впоратися з
ними.
2.1.2.1 Мова програмування
2.1.2.3 Ціна
2.1.2.4 Висновки
Кожен з рушіїв має свої плюси та мінуси. Для створення гри в даній роботі
буде використано Unity через його підтримку C# та велику кількість нового
матеріалу для самостійного навчання. Версія рушія буде 2018.3.14f1 Personal.
45
Unity можна завантажити напряму або з Unity Hub, яка допомагає шукати,
завантажувати та управляти проектами та завантаженнями. За допомогою Unity
Hub можна вручну додати версію редактора (Рисунок 2.8).
Усі моделі та текстури були завантажені з Unity Asset Store. Моделі зброї та
патронів були завантажені з платформи Scetchfab.
2.3.4 Плагіни
Для створення гри були використані онлайн уроки ютуб каналів Jimmy
Vegas [28] та Brackeys [29]. У разі виникнення помилок під час розробки
доводилося шукати вирішення проблеми на форумах або самостійно вирішувати
проблему.
52
3 РОЗРОБКА ГРИ
3.1.1 A001Spider.cs
3.1.2 A002Door.cs
3.1.3 AmmoPickup.cs
3.1.4 AmmoPickupSMG.cs
3.1.5 BarrelBang.cs
3.1.6 BarrelBlow.cs
3.1.7 CaveDoor.cs
3.1.8 CaveDoorExit.cs
3.1.9 CreackyDoorOpen.cs
3.1.10 CredToMenu.cs
3.1.11 CrossAnimate.cs
3.1.12 CutScene01.cs
3.1.13 EnemyScript.cs
3.1.14 EnemyScriptSpider.cs
3.1.15 GameOverToMenu.cs
3.1.16 GlobalAmmo.cs
3.1.17 GlobalHealth.cs
3.1.18 GlobalScore.cs
3.1.19 GunFire.cs
3.1.20 GunFireSMG.cs
3.1.21 HandGunDamage.cs
3.1.22 HandGunReload.cs
3.1.23 HealthMonitor.cs
3.1.24 MainMenuOptions.cs
3.1.25 OpenDoor001.cs
3.1.27 PickUp9mm.cs
3.1.28 PickUpSMG.cs
3.1.29 PlayerCasting.cs
3.1.30 RespawnLevel.cs
Перезавантажує рівень.
3.1.31 SkyRotation.cs
3.1.32 SMGReload.cs
3.1.33 SniperScopeActive.cs
Скрипт для прицілювання. При натисканні правої кнопки миші поле зору
зменшується та наскладується зображення прицілу. Коли кнопка відпускається,
тоді поле зору повертається до норми.
3.1.34 SpiderFollow.cs
3.1.35 SpiderScore.cs
3.1.36 SplashToMenu.cs
3.1.37 WeaponSwitch.cs
58
3.1.38 ZombieFollow.cs
3.1.39 ZombieScore.cs
3.1.40 ZScore25.cs
3.1.41 ZScore50.cs
3.1.42 ZScore100.cs
Кнопка Play запускає гру. Кнопка Load створена для майбутньої можливості
збереження гри з усією статистикою гравця. Кнопка Credits запускає титри до гри
(Рисунок 3.14). Після їх закінчення гравця переносить назад до головного меню.
68
3.4 Висновки
Була створена гра на рушії Unity під Windows. Гра представляє собою
шутер від першого обличчя, де гравцю потрібно знайти вихід на інший рівень. В
якості перешкоди на гравця будуть нападати зомбі та павуки. В якості допомоги
по рівню будуть розкидані патрони для запобігання втрати боєздатності
незалежно від навичок гравця у стрільбі.
69
ВИСНОВКИ
26. Choose the plan that is right for you [Електронний ресурс]. – Режим
доступу: URL: https://store.unity.com/compare-plans
27. Learning the interface [Електронний ресурс]. – Режим доступу: URL:
https://docs.unity3d.com/2018.3/Documentation/Manual/LearningtheInterface.html
28. [COMPLETE] How to Make An FPS Unity Tutorials [Електронний ресурс].
– Режим доступу: URL: https://www.youtube.com/playlist?list=PLZ1b66Z1KFKh-
auyvzNkOBFLWf6dH6iEH
29. Brackeys [Електронний ресурс]. – Режим доступу: URL:
https://www.youtube.com/user/Brackeys
73
ДОДАТКИ
74
Найменування
Документація
на ігровому
рушії Unity»
Комплекси
Операційна система
Microsoft Windows 10
Unity
ДОДАТОК А
A001Spider.cs
using System.Collections;
76
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
A002Door.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
AmmoPickup.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
AmmoSound.Play();
if (GlobalAmmo.LoadedAmmo == 0)
{
GlobalAmmo.LoadedAmmo += 10;
this.gameObject.SetActive(false);
}
else
{
GlobalAmmo.CurrentAmmo += 10;
this.gameObject.SetActive(false);
}
}
}
AmmoPickupSMG.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if (GlobalAmmo.LoadedAmmo == 0)
{
GlobalAmmo.LoadedAmmo += 30;
this.gameObject.SetActive(false);
}
else
{
GlobalAmmo.CurrentAmmo += 30;
this.gameObject.SetActive(false);
}
}
}
BarrelBang.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
if (EnemyHealth <= 0)
{
TheBarrel.SetActive(false);
FakeBarrel.SetActive(true);
}
}
CaveDoor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
void Update()
{
TheDistance = PlayerPrefs.GetFloat("TheCasting");
takenGun = PlayerPrefs.GetInt("TakeAGun");
}
void OnMouseOver()
{
if (takenGun == 1) {
if (TheDistance <= 3)
{
ActionDisplay.GetComponent<Text>().text = "Enter Cave";
ActionDisplay.SetActive(true);
}
if (Input.GetButtonDown("Action"))
{
if (TheDistance <= 3)
79
{
creakSound.Play();
fadeOutScreen.SetActive(true);
StartCoroutine(EnterTheCave());
GetComponent<BoxCollider>().enabled = false;
ActionDisplay.SetActive(false);
SceneManager.LoadScene(6);
}
}
}
}
void OnMouseExit()
{
ActionDisplay.SetActive(false);
}
IEnumerator EnterTheCave()
{
fadeOutScreen.GetComponent<Animation>().Play("FadeOutAnim");
yield return new WaitForSeconds(1.5f);
SceneManager.LoadScene(6);
}
}
CaveDoorExit.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
void Update()
{
TheDistance = PlayerPrefs.GetFloat("TheCasting");
}
void OnMouseOver()
{
if (TheDistance <= 3)
{
ActionDisplay.GetComponent<Text>().text = "End Game";
ActionDisplay.SetActive(true);
}
if (Input.GetButtonDown("Action"))
{
if (TheDistance <= 3)
{
creakSound.Play();
StartCoroutine(ExitTheCave());
GetComponent<BoxCollider>().enabled = false;
ActionDisplay.SetActive(false);
SceneManager.LoadScene(1);
}
}
80
void OnMouseExit()
{
ActionDisplay.SetActive(false);
}
IEnumerator ExitTheCave()
{
yield return new WaitForSeconds(1.5f);
SceneManager.LoadScene(1);
}
}
CreackyDoorOpen.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
void Update()
{
TheDistance = PlayerPrefs.GetFloat("TheCasting");
}
void OnMouseOver()
{
if (TheDistance <= 3)
{
ActionDisplay.GetComponent<Text>().text = "Open Door";
ActionDisplay.SetActive(true);
}
if (Input.GetButtonDown("Action"))
{
if (TheDistance <= 3)
{
GetComponent<BoxCollider>().enabled = false;
ActionDisplay.SetActive(false);
TheDoor.GetComponent<Animation>().Play("OpenDoorAnim");
CreakSound.Play();
}
}
}
void OnMouseExit()
{
ActionDisplay.SetActive(false);
}
}
CredToMenu.cs
using System.Collections;
81
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
void Start()
{
StartCoroutine(ReturnToMenu());
}
IEnumerator ReturnToMenu()
{
yield return new WaitForSeconds(11);
SceneManager.LoadScene(1);
}
CrossAnimate.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
if (GlobalAmmo.LoadedAmmo >= 1) {
if (Input.GetButtonDown("Fire1"))
{
UpCurs.GetComponent<Animator>().enabled = true;
DownCurs.GetComponent<Animator>().enabled = true;
LeftCurs.GetComponent<Animator>().enabled = true;
RightCurs.GetComponent<Animator>().enabled = true;
StartCoroutine(WaitingAnim());
}
}
}
IEnumerator WaitingAnim()
{
yield return new WaitForSeconds(0.1f);
UpCurs.GetComponent<Animator>().enabled = false;
DownCurs.GetComponent<Animator>().enabled = false;
LeftCurs.GetComponent<Animator>().enabled = false;
RightCurs.GetComponent<Animator>().enabled = false;
}
}
CutScene01.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
82
void Start()
{
StartCoroutine(CutSceneBegin());
}
IEnumerator CutSceneBegin()
{
yield return new WaitForSeconds(4.5f);
Cam2.SetActive(true);
Cam1.SetActive(false);
yield return new WaitForSeconds(4.5f);
ThePlayer.SetActive(true);
TheUI.SetActive(true);
Cam2.SetActive(false);
}
}
EnemyScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
if (EnemyHealth <= 0)
{
this.GetComponent<ZombieFollow>().enabled = false;
TheZombie.GetComponent<Animation>().Play("Dying");
StartCoroutine(EndZombie());
}
}
IEnumerator EndZombie()
{
yield return new WaitForSeconds(1);
Destroy(gameObject);
}
}
EnemyScriptSpider.cs
using System.Collections;
83
using System.Collections.Generic;
using UnityEngine;
void Update()
{
if (EnemyHealth <= 0)
{
this.GetComponent<SpiderFollow>().enabled = false;
TheSpider.GetComponent<Animation>().Play("die");
}
}
IEnumerator EndZombie()
{
yield return new WaitForSeconds(1);
Destroy(gameObject);
}
}
GameOverToMenu.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
void Start()
{
StartCoroutine(ReturnToMenuGO());
}
IEnumerator ReturnToMenuGO()
{
yield return new WaitForSeconds(3);
SceneManager.LoadScene(1);
}
GlobalAmmo.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
void Update()
{
InternalAmmo = CurrentAmmo;
InternalLoaded = LoadedAmmo;
PlayerPrefs.SetInt("AmmoLevel", CurrentAmmo);
AmmoDisplay.GetComponent<Text>().text = "" + InternalAmmo;
LoadedDisplay.GetComponent<Text>().text = "" + LoadedAmmo;
}
}
GlobalHealth.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
GlobalScore.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
void Update()
{
85
InternalScore = CurrentScore;
ScoreText.GetComponent<Text>().text = "" + InternalScore;
}
}
GunFire.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
if (GlobalAmmo.LoadedAmmo >= 1) {
if (Input.GetButtonDown("Fire1"))
{
AudioSource gunsound = GetComponent<AudioSource>();
gunsound.Play();
Flash.SetActive(true);
StartCoroutine(MuzzleOff());
GetComponent<Animation>().Play("GunShot");
GlobalAmmo.LoadedAmmo -= 1;
}
}
}
IEnumerator MuzzleOff()
{
yield return new WaitForSeconds(0.1f);
Flash.SetActive(false);
}
}
GunFireSMG.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
AmmoCount = GlobalAmmo.LoadedAmmo;
if (Input.GetButton("Fire1"))
86
{
if (AmmoCount >= 1)
{
if (Firing == 0)
{
StartCoroutine(SMGFire());
}
}
}
}
IEnumerator SMGFire()
{
Firing = 1;
UpCurs.GetComponent<Animator>().enabled = true;
DownCurs.GetComponent<Animator>().enabled = true;
LeftCurs.GetComponent<Animator>().enabled = true;
RightCurs.GetComponent<Animator>().enabled = true;
GlobalAmmo.LoadedAmmo -= 1;
SMGSound.Play();
MuzzleFlash.SetActive(true);
TheSMG.GetComponent<Animator>().enabled = true;
yield return new WaitForSeconds(0.1f);
MuzzleFlash.SetActive(false);
TheSMG.GetComponent<Animator>().enabled = false;
UpCurs.GetComponent<Animator>().enabled = false;
DownCurs.GetComponent<Animator>().enabled = false;
LeftCurs.GetComponent<Animator>().enabled = false;
RightCurs.GetComponent<Animator>().enabled = false;
Firing = 0;
}
}
HandGunDamage.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Start()
{
DamageAmount = 5;
}
void Update()
{
if (GlobalAmmo.LoadedAmmo >= 1)
{
if (Input.GetButtonDown("Fire1"))
87
{
RaycastHit Shot;
if (Physics.Raycast(transform.position,
transform.TransformDirection(Vector3.forward), out Shot))
{
TargetDistance = Shot.distance;
if (TargetDistance < AllowedRange)
{
if (Physics.Raycast (transform.position,
transform.TransformDirection(Vector3.forward), out hit))
{
if (hit.transform.tag == "Zombie")
{
Instantiate(TheBlood, hit.point,
Quaternion.FromToRotation(Vector3.up, hit.normal));
}
if (hit.collider.CompareTag("ZombieHead"))
{
DamageAmount = 10;
Instantiate(TheBlood, hit.point,
Quaternion.FromToRotation(Vector3.up, hit.normal));
}
if (hit.transform.tag == "Spider")
{
Instantiate(TheBloodGreen, hit.point,
Quaternion.FromToRotation(Vector3.up, hit.normal));
}
if (hit.transform.tag == "Untagget")
{
Instantiate(TheBullet, hit.point,
Quaternion.FromToRotation(Vector3.up, hit.normal));
}
}
Shot.transform.SendMessage("DeductPoints", DamageAmount,
SendMessageOptions.DontRequireReceiver);
DamageAmount = 5;
}
}
}
}
}
HandGunReload.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Start()
{
GunComponent = GetComponent<GunFire>();
}
void Update()
{
ClipCount = GlobalAmmo.LoadedAmmo;
ReserveCount = GlobalAmmo.CurrentAmmo;
if (ReserveCount == 0)
{
ReloadAvailable = 0;
}
else
{
ReloadAvailable = 10 - ClipCount;
}
if (Input.GetButtonDown("Reload"))
{
if (ReloadAvailable >= 1)
{
if (ReserveCount <= ReloadAvailable)
{
GlobalAmmo.LoadedAmmo += ReserveCount;
GlobalAmmo.CurrentAmmo -= ReserveCount;
ActionReload();
}
else
{
GlobalAmmo.LoadedAmmo += ReloadAvailable;
GlobalAmmo.CurrentAmmo -= ReloadAvailable;
ActionReload();
}
}
StartCoroutine(EnableScripts());
}
}
HealthMonitor.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
CurrentHealth = GlobalHealth.PlayerHealth;
if (CurrentHealth == 8)
{
if (Health04.transform.localScale.y < 0.0f)
{
Health04.SetActive(false);
}
else
{
Health04.transform.localScale -= new Vector3(0.0f, 0.05f, 0.0f);
}
}
if (CurrentHealth == 6)
{
if (Health03.transform.localScale.y < 0.0f)
{
Health03.SetActive(false);
}
else
{
Health03.transform.localScale -= new Vector3(0.0f, 0.05f, 0.0f);
}
}
if (CurrentHealth == 4)
{
if (Health02.transform.localScale.y < 0.0f)
{
Health02.SetActive(false);
}
else
{
Health02.transform.localScale -= new Vector3(0.0f, 0.05f, 0.0f);
}
}
if (CurrentHealth == 2)
{
if (Health01.transform.localScale.y < 0.0f)
{
Health01.SetActive(false);
}
90
else
{
Health01.transform.localScale -= new Vector3(0.0f, 0.05f, 0.0f);
}
}
if (CurrentHealth == 0)
{
if (Health00.transform.localScale.y < 0.0f)
{
Health00.SetActive(false);
}
else
{
Health00.transform.localScale -= new Vector3(0.0f, 0.05f, 0.0f);
}
}
}
}
MainMenuOptions.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
OpenDoor001.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
void Update()
{
TheDistance = PlayerCasting.DistanceFromTarget;
}
void OnMouseOver()
{
if (TheDistance <= 2)
{
TextDisplay.GetComponent<Text>().text = "Press to open!";
}
if (Input.GetButtonDown("Action") && DoorOpen == false)
{
if (TheDistance <= 2)
{
DoorOpen = true;
ObjectiveComplete.SetActive(true);
StartCoroutine("OpenTheDoor");
}
}
}
void OnMouseExit()
{
TextDisplay.GetComponent<Text>().text = "";
}
IEnumerator OpenTheDoor()
{
TheDoor.GetComponent<Animator>().enabled = true;
yield return new WaitForSeconds(1);
TheDoor.GetComponent<Animator>().enabled = false;
yield return new WaitForSeconds(5);
TheDoor.GetComponent<Animator>().enabled = true;
yield return new WaitForSeconds(1);
TheDoor.GetComponent<Animator>().enabled = false;
DoorOpen = false;
}
}
PauseGame.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.Characters.FirstPerson;
using UnityEngine.SceneManagement;
public class PauseGame : MonoBehaviour
{
public bool Paused = false;
public GameObject ThePlayer;
public GameObject PauseMenu;
void Update()
{
if (Input.GetButtonDown("Cancel"))
{
if (Paused == false)
{
92
Time.timeScale = 0;
Paused = true;
PauseMenu.SetActive(true);
ThePlayer.GetComponent<FirstPersonController>().enabled = false;
Cursor.visible = true;
}
else
{
ThePlayer.GetComponent<FirstPersonController>().enabled = true;
Paused = false;
PauseMenu.SetActive(false);
Time.timeScale = 1;
}
}
}
PickUp9mm.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
void Update()
{
TheDistance = PlayerCasting.DistanceFromTarget;
void OnMouseOver()
{
if (TheDistance <= 2)
{
TextDisplay.GetComponent<Text>().text = "Take 9mm Pistol";
}
if (Input.GetButtonDown("Action"))
{
if (TheDistance <= 2)
{
StartCoroutine(TakeNineMil());
ObjectiveComplete.SetActive(true);
}
}
}
void OnMouseExit()
{
TextDisplay.GetComponent<Text>().text = "";
}
IEnumerator TakeNineMil()
{
PlayerPrefs.SetInt("TakeAGun", 1);
DoorStopper.SetActive(false);
PickUpAudio.Play();
transform.position = new Vector3(0, -1000, 0);
FakeGun.SetActive(false);
RealGun.SetActive(true);
AmmoDisplay.SetActive(true);
WeaponHolder.SetActive(true);
AnotherWeapon2.SetActive(false);
yield return new WaitForSeconds(0.1f);
}
}
PickUpSMG.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
void Update()
{
TheDistance = PlayerCasting.DistanceFromTarget;
void OnMouseOver()
{
if (TheDistance <= 2)
{
TextDisplay.GetComponent<Text>().text = "Take SMG";
}
if (Input.GetButtonDown("Action"))
{
if (TheDistance <= 2)
{
StartCoroutine(TakeNineMil());
Mechanics.SetActive(true);
ObjectiveComplete.SetActive(true);
}
}
}
void OnMouseExit()
{
TextDisplay.GetComponent<Text>().text = "";
}
IEnumerator TakeNineMil()
{
PickUpAudio.Play();
transform.position = new Vector3(0, -1000, 0);
FakeGun.SetActive(false);
RealGun.SetActive(true);
AmmoDisplay.SetActive(true);
WeaponHolder.SetActive(true);
AnotherWeapon1.SetActive(false);
yield return new WaitForSeconds(0.1f);
}
}
PlayerCasting.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
RaycastHit hit;
if (Physics.Raycast(transform.position,
transform.TransformDirection(Vector3.forward), out hit))
{
ToTarget = hit.distance;
DistanceFromTarget = ToTarget;
PlayerPrefs.SetFloat("TheCasting", DistanceFromTarget);
}
}
}
RespawnLevel.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
void Start()
{
SceneManager.LoadScene(4);
}
SkyRotation.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
RenderSettings.skybox.SetFloat("_Rotation", Time.time * RotateSpeed);
}
}
SMGReload.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
ClipCount = GlobalAmmo.LoadedAmmo;
ReserveCount = GlobalAmmo.CurrentAmmo;
if (ReserveCount == 0)
{
ReloadAvailable = 0;
}
else
{
ReloadAvailable = 15 - ClipCount;
}
if (Input.GetButtonDown("Reload"))
{
if (ReloadAvailable >= 1)
{
if (ReserveCount <= ReloadAvailable)
{
GlobalAmmo.LoadedAmmo += ReserveCount;
GlobalAmmo.CurrentAmmo -= ReserveCount;
ActionReloadSMG();
}
else
{
GlobalAmmo.LoadedAmmo += ReloadAvailable;
GlobalAmmo.CurrentAmmo -= ReloadAvailable;
ActionReloadSMG();
}
}
StartCoroutine(EnableScripts());
}
}
MechanicsObject.SetActive(false);
ReloadSound.Play();
GetComponent<Animation>().Play("SMGReload");
}
}
SniperScopeActive.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
if (Input.GetMouseButtonDown(1))
{
if (zoomingIn == false)
{
sniperScopeTex.SetActive(true);
originalCursor.SetActive(false);
StartCoroutine(ZoomingCam());
zoomingIn = true;
}
}
if (Input.GetMouseButtonUp(1))
{
StopAllCoroutines();
fieldView = 60;
playerCam.GetComponent<Camera>().fieldOfView = fieldView;
sniperScopeTex.SetActive(false);
originalCursor.SetActive(true);
zoomingIn = false;
}
}
IEnumerator ZoomingCam()
{
while (fieldView > 25)
{
playerCam.GetComponent<Camera>().fieldOfView = fieldView;
fieldView -= 2;
yield return new WaitForSeconds(0.01f);
}
}
SpiderFollow.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
98
if (AttackTrigger == 1)
{
if (IsAttacking == 0)
{
StartCoroutine(EnemyDamage());
}
EnemySpeed = 0;
TheEnemy.GetComponent<Animation>().Play("attack");
}
}
AttackTrigger = 1;
}
99
IEnumerator EnemyDamage()
{
IsAttacking = 1;
PainSound = Random.Range(1, 4);
yield return new WaitForSeconds (0.4f);
ScreenFlash.SetActive(true);
GlobalHealth.PlayerHealth -= 2;
if (PainSound == 1)
{
Hurt01.Play();
}
if (PainSound == 2)
{
Hurt02.Play();
}
if (PainSound == 3)
{
Hurt03.Play();
}
yield return new WaitForSeconds(0.09f);
ScreenFlash.SetActive (false);
yield return new WaitForSeconds(1);
IsAttacking = 0;
}
}
SpiderScore.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
SplashToMenu.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
void Start()
{
StartCoroutine(SplashFinish());
}
IEnumerator SplashFinish()
100
{
yield return new WaitForSeconds(5.5f);
SceneManager.LoadScene(1);
}
}
WeaponSwitch.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
void Update()
{
int previousSelectedWeapon = selectedWeapon;
if (Input.GetKeyDown(KeyCode.Alpha1))
{
selectedWeapon = 0;
}
if (previousSelectedWeapon != selectedWeapon)
{
SelectWeapon();
}
}
void SelectWeapon()
{
int i = 0;
foreach (Transform weapon in transform)
{
101
if (i == selectedWeapon)
weapon.gameObject.SetActive(true);
else
weapon.gameObject.SetActive(false);
i++;
}
}
}
ZombieFollow.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
if (AttackTrigger == 1)
{
if (IsAttacking == 0)
{
StartCoroutine(EnemyDamage());
102
}
EnemySpeed = 0;
TheEnemy.GetComponent<Animation>().Play("Attacking");
}
}
AttackTrigger = 1;
IEnumerator EnemyDamage()
{
IsAttacking = 1;
PainSound = Random.Range(1, 4);
yield return new WaitForSeconds (0.4f);
ScreenFlash.SetActive(true);
GlobalHealth.PlayerHealth -= 2;
if (PainSound == 1)
{
Hurt01.Play();
}
if (PainSound == 2)
{
Hurt02.Play();
}
if (PainSound == 3)
{
Hurt03.Play();
}
yield return new WaitForSeconds(0.09f);
ScreenFlash.SetActive (false);
yield return new WaitForSeconds(1);
IsAttacking = 0;
}
}
ZombieScore.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ZScore25.cs
103
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ZScore50.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
ZScore100.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;