UnrealScript
UnrealScript (також UScript) - це рідна скриптова мова Unreal Engine, яка використовувалась для написання коду та подій ігрового процесу на Unreal Engine до релізу 4-ї версії цього рушія. Мова була розроблена для простого, високорівневого програмування ігор. Інтерпретатор UnrealScript був запрограмований Тімом Свіні, який також створив попередню скриптову мову гри ZZT-oop. UnrealScript компілюється, але не є частиною основного виконуваного файлу. Це робить її ідеальним засобом реалізації та повторення нових елементів ігрового процесу без необхідності перекомпільовувати весь двигун при внесенні змін. Вихідний код є закритим.
Unreal Script | |
---|---|
Парадигма | об'єктно-орієнтована, узагальнена |
Дата появи | 1998 |
Творці | Тім Свіні |
Розробник | Epic Games |
Останній реліз | |
Система типізації | статична, строга типізація, safe typing |
Основні реалізації | віртуальна машина Unreal Engine |
Операційна система | Мультиплатформна |
Ліцензія | UDK Licensing Resources |
Вебсайт | docs.unrealengine.com/udk/Three/UnrealScriptHome.html |
Подібно до Java, UnrealScript є об'єктно-орієнтованою без багаторазового успадкування (усі класи успадковуються від загального класу Object), а класи визначаються в окремих файлах, названих відповідно до класу, який вони визначають. У той же час, оскільки UnrealScript використовують в розробці відеоігор, деякі принципи та методології відрізняються від традиційного програмування. Наприклад, немає стандартних явних конструкторів або деструкторів для об’єктів, які можуть викликати суперечність з тими, що використовуються для більш традиційних мов програмування. На відміну від Java, UnrealScript не має обгортки об'єктів для примітивних типів. Інтерфейси підтримувалися лише в Unreal Engine 3-го покоління та кількох іграх Unreal Engine 2. UnrealScript підтримує перевантаження оператора, але не перевантаження функцій, за винятком додаткових параметрів.
У березні 2014 року компанія Epic Games заявила, що Unreal Engine 4 підтримуватиме не UnrealScript, а сценарії(скрипти) ігор на C++. Візуальні скрипти будуть підтримуватися системою візуалізації Blueprints, заміною попередній системі Kismet.
Одним із ключових моментів у розвитку Unreal Engine 4 була серія проведених нами дебатів про UnrealScript - мову сценаріїв, яку я будував протягом трьох поколінь. Нашою метою було зробити її конкурентоспроможною у майбутньому. Ми продовжували переглядати все більше та більше варіантів того, що нам потрібно зробити, щоб оновити її, і хто міг би виконати цю роботу. Ця справа ставала дуже громіздкою. Відбулась масштабна зустріч, на котрій ми спробували розібратися, спробували вирішити, що вирізати, що залишити і ... був момент, коли я подивився на все і сказав: ‘Ви знаєте, все, що ви пропонуєте додавати до UnrealScript, вже є на C ++. Чому б нам просто не вбити UnrealScript, і не перейти на чистий C ++? ‘. — Свіні, Gamasutra, 2017[1]
Приклад коду
Історично програмісти відеоігор використовували концепцію станів з тих пір, як ігри пройшли епоху «понгу». Стани (і те, що відоме як "програмування машин стану") - це природний спосіб зробити складну поведінку об'єкта керованою. Однак до UnrealScript стани не підтримувалися на мовному рівні, що вимагало від розробників створювати оператори «перемикання» C/C ++ на основі стану об’єкта. Такий код було важко писати та оновлювати.
UnrealScript підтримує стани на мовному рівні. Тому в цій мові можна писати функції та код, які існують у певному стані. Ці функції викликаються лише тоді, коли актор знаходиться в ньому. Притому кожен актор завжди знаходиться в одному і лише одному стані, котрий відображає дію, яку він хоче виконати.
Приклад станів зі сценарію TriggerLight:
// Trigger turns the light on.
state() TriggerTurnsOn
{
function Trigger( actor Other, pawn EventInstigator )
{
Trigger = None;
Direction = 1.0;
Enable( 'Tick' );
}
}
// Trigger turns the light off.
state() TriggerTurnsOff
{
function Trigger( actor Other, pawn EventInstigator )
{
Trigger = None;
Direction = -1.0;
Enable( 'Tick' );
}
}
}
Тут оголошуються два різні стани (TriggerTurnsOn та TriggerTurnsOff), і різні версії функції Trigger у кожному стані. Хоча можлива реалізація без станів, використання станів робить код більш модульним та розширеним: у UnrealScript можна легко підкласувати існуючий клас, додавати нові стани та функції. Якщо намагатися зробити це без станів, отриманий код згодом було б складніше розширити.
Існують три основні приховані функції, доступні для всіх акторів:
- Sleep (плаваючі секунди) - призупиняє виконання стану на певний час, а потім продовжує.
- FinishAnim () - чекає, поки поточна анімаційна послідовність, завершиться, а потім продовжується. Ця функція полегшує написання сценаріїв на основі анімації, сценарії виконання яких регулюються анімацією сітки. Наприклад, більшість сценаріїв ШІ керуються анімацією (на відміну від часу), тому що плавна анімація є ключовою метою системи ШІ.
- FinishInterpolation () - чекає завершення поточного руху InterpolationPoint, а потім продовжує.
Три рідні функції UnrealScript особливо корисні при написанні коду стану:
- Функція "Goto ('LabelName')" (подібно до C/C ++/Basic goto) у стані змушує код стану продовжувати виконуватись за вказаною міткою.
- Спеціальна команда "Stop" всередині стану припиняє виконання коду стану. Воно не триватиме, доки ви не перейдете до нового стану або нової мітки в поточному стані.
- Функція "GotoState" змушує актора переходити до нового стану та за бажанням продовжувати на зазначеній мітці.
Приклад:
// This is the automatic state to execute.
auto state Idle
{
// When touched by another actor...
function Touch( actor Other )
{
`log( "I was touched, so I'm going to Attacking" );
GotoState( 'Attacking' );
`log( "I have gone to the Attacking state" );
}
Begin:
`log( "I am idle..." );
sleep( 10 );
goto 'Begin';
}
// Attacking state.
state Attacking
{
Begin:
`log( "I am executing the attacking state code" );
...
}
При виконанні отримуємо:
I am idle...
I am idle...
I am idle...
I was touched, so I'm going to Attacking
I have gone to the Attacking state
I am executing the attacking state code
Структура
UnrealScript має статичну типізацію. Широко використовується паралелізм виконання завдань - як правило, кожен об'єкт має свій потік виконання в рамках віртуальної машини. Присутня широка підтримка типів, часто використовуються вектор, кути Ейлера, матриці і т.п.
Основні концепції програмування мови UnrealScript, витікають із Java:
- відсутність покажчиків і автоматичне прибирання сміття;
- неможливість множинного успадкування класів;
- строга перевірка типів при компіляції;
- безпечне виконання на стороні клієнта "sandbox" (пісочниці);
- знайомий зовнішній вигляд коду, подібний до C / C ++ і Java.
Для забезпечення високорівневого програмування UnrealScript працює на рівні об'єктів і взаємодій, а не на рівні бітів і пікселів. Однак в цілях збільшення потужності та забезпечення простоти мови доводиться жертвувати швидкістю виконання.
Прості типи даних
Тип | Опис типу та набір його значень |
---|---|
bool | true, false |
byte | ціле число з діапазоном значень від 0 до 255 |
int | ціле 32-х бітне число з діапазоном значень від −2 147 483 648 до 2 147 483 647 |
float | 32-х бітне число з рухомою комою |
string | рядок символів Unicode |
enum | тип перерахування, що містить набір іменованих констант 0 і 1 |
name | тип, що вказує ім'я класу, стану та ін. |
Object | посилання на об'єкт |
Actor | посилання на об'єкт класу Actor або успадкованого від нього |
Class | посилання вказує на тип класу чи успадкованого від нього класу |
Struct | структура, що складається із фіксованого числа полів |
Array | статичний масив |
Документація та підручники
Посилання
Примітки
- WawroBloggerMarch 01, Alex; 2017 (1 березня 2017). For Tim Sweeney, advancing Epic means racing into AR and VR. Game Developer (англ.). Процитовано 6 жовтня 2021.