Иллюстрация

ОБУЧЕНИЕ СКРИПТИНГУ: ОСНОВЫ

Для начала было бы хорошо если бы ты, мой дорогой друг, знал основы работы с редактором RuneED (или UnrealED). Умел ставить акторы, знал где посмотреть и изменить параметры этих акторов и какие акторы вообще бывают и для чего используются. Ну и было бы здорово наличие базовых знаний программирования.

Если уж так вышло что ты ничего не знаешь – не беда, возможно в процессе чтения данной статьи что-нибудь, да поймешь.

Сперва нужно понять, как создавать эти скрипты, что можно делать, что нельзя и как создать свой пэкедж.

Если очень тщательно присмотреться, то справа можно увидеть здоровенный такой список классов, которые используются в игре:

Для того чтобы посмотреть, как работает тот или иной объект достаточно дважды нажать на него в списке и откроется меню скриптинга. Теперь я могу тебя поздравить! Ты уже наполовину проггер!

Но сразу хочу предупредить: НИЧЕГО НЕ ПИШИ И НЕ МЕНЯЙ В КЛАССАХ, КОТОРЫЕ ОТНОСЯТСЯ К САМОЙ ИГРЕ (КОТОРЫЕ ТЫ НЕ СОЗДАВАЛ)!

Это важно, потому что иначе ты внесешь изменения в базовые пэкеджи игры. Работать игра скорее всего будет, но, например при игре по сети тебя не будет пускать на сервера из-за отличающихся пэкеджей.

Итак, как же нам создать наш собственный пэкедж чтобы не ломать базовый? Для этого достаточно создать любой новый обьект для твоего пэкеджа (даже если его еще не существует). Порядок действий такой:

1. Придумываем что за обьект будет в нашем пэкедже и находим в списке справа подходящую для него болванку. Во всем последующем туториале я буду использовать за основу класс RuneOfHealth, так что советую и тебе, чтобы понимать, что происходит. Находится он в Actor->Inventory->Runes->RuneOfHealth

2. Кликаем на него правой кнопкой мыши

3. Выбираем пункт: “Create new class below …”

4. В появившемся окошке необходимо заменить имя обьекта и, ОЧЕНЬ ВАЖНО, заменить название пэкеджа RuneI на название твоего нового пэкеджа (которого еще не существует). В моем случае это будет MyLearn

5. Жмем “Create this actor class” и у нас открывается практически пустое окно с кодом нашего нового актора: HellRune

Дальше, прежде чем начать что-либо кодить нам нужно сделать еще парочку подготовительных шагов:

Во-первых, сразу же жмем кнопку F7. Эта кнопка компилирует все измененные классы игры, в том числе наш новый класс. В процессе этой компиляции движок ищет наш пэкедж MyLearn и не находит его, поэтому он просто создает для него новый. Теперь, чтобы убедиться, что все прошло успешно нужно зайти в папку с игрой, залететь в папку System и найти там наш новый файлик: MyLearn.u. Если этот файлик там есть – значит ты успешно нажал на кнопку F7 и создал свой первый пэкедж! Поздравляю!

Во-вторых: не спеши закрывать папку. Найди в ней файлик Rune.ini и открой с помощью блокнота (или лучше с помощью notepad++). Там тебе нужно найти раздел [Editor.EditorEngine] и строчки начинающиеся с EditPackages=…
После всех этих EditPackages добавь новую строчку со своим пэкеджем, например вот так:

Это нужно для того, чтобы при запуске RuneED твой пэкедж автоматически подгружался в редактор и все его классы были видны в списке справа.

 

Первоначальная настройка закончена, теперь можно переходить к кодингу!

Давай предположим, что мы хотим сделать такую руну, при поедании которой игрока подбросит вверх в воздух.

Для этого двойным нажатием открываем (если закрыли) наш класс HellRune. Он вложен в RuneOfHealth.

Сразу хочу объяснить одну штуку: даже несмотря на то, что окно с кодом HellRune практически пустое, на самом деле наш класс содержит (правильнее: наследует) ПОЛНОСТЬЮ весь код всех своих родителей. Для нашей руны родителями являются снизу-вверх: RuneOfHealth, Runes, Pickup, Inventory, Actor, Object. Это значит, что весь код из этих классов как бы есть в нашей HellRune.

Но, к счастью, мы можем менять наследованный функционал, не заходя в родителей. Для этого достаточно найти нужную тебе функцию в родителе, скопировать ее, вставить в свой класс и переписать так как тебе нужно.

Давай предположим, что мы хотим, чтобы нашу руну могли брать только те игроки, у которых больше половины здоровья.

Для этого начинам прочесывать родителей снизу-вверх в поисках чего-то похожего и находим в классе RuneOfHealth функцию с названием PawnWantsRune(…).

Как понятно из названия эта функция производит проверку того, может ли поднять наш игрок эту руну или нет. Для руны здоровья здесь указано, что игрок может поднять эту руну если у него меньше 200хп, не полное хп или отсутствует одна из рук. В целом мы можем просто поменять эту проверку. Просто целиком копируем функцию, вставляем в наш класс и сразу жмем F7. КРАЙНЕ советую почаще жать эту кнопку, так как это альтернатива сохранению, но только для скриптов. Никто не знает когда редактор вылетит с ошибкой. Так же нажатие этой клавиши покажет ошибки в коде.

Теперь давай поменяем проверку так, как нам это нужно. Это будет выглядеть следующим образом (так же я удалил зеленый комментарий, так как он нам не нужен):

И не забываем прожимать F7, а то код не применится и при запуске ничего не изменится!

Можно немного потестировать: поставить руну на карту и попробовать взять руну. Она должна взяться без проблем. Но если ты каким-нибудь образом надамажишь себя более чем на пол хп, то руну взять уже не получится.

Теперь немного разберем код.

========================== ========================== ==========================

ВАЖНО: Если тебя не особо интересуют подробности того как оно работает, то ты можешь скипнуть несколько следующих абзацев. Я даже указал место до куда можно скипнуть =)

В самом верху мы видим зеленые строчки: это комментарии, которые создались автоматически. Чтобы написать свой комментарий в коде, достаточно в начале строки добавить //

Например:

Затем вы видим строчку, начинающуюся со слова class. Эта строчка должна быть в самом вверху класса. Она указывает само название класса (HellRune) и прямого родителя этого класса после ключевого слова expands (в данном случае наш родитель это RuneOfHealth).

А дальше – мы уже вольны писать наши функции. Функция – это, по сути, команда. Этакий кусок кода, который выполняется при вызове этой команды.

Каждая функция имеет свое название (PawnWantsRune) через которое данная функция вызывается где-то в другом месте в коде следующим образом: PawnWantsRune(…)

Так же стоит знать, что функции могут возвращать какой-то результат своего выполнения в место, где их вызвали, а могут ничего не возвращать. Наша функция PawnWantsRune возвращает значение типа bool (указывается сразу после слова function). Если ничего не указано – значит функция ничего не возвращает. Переменная типа bool может иметь только 2 значения: true или false.

В данном случае наша функция ДОЛЖНА вернуть true если игрок МОЖЕТ взять руну и false если НЕ МОЖЕТ.

Какое конкретно значение возвращает функция указывается после слова return. Например: return true;

В нашей функции мы возвращаем результат от (Other.Health > Other.MaxHealth / 2). В этом случае сначала просчитывается это выражение и его результат возвращается через return. Т.е. тут мы берем текущее хп игрока (Other.Health) и смотрим больше ли оно чем половина максимального хп игрока (Other.MaxHealth / 2). Other – это игрок который хочет взять руну.

Еще пара слов про функции: функции могут получать какие-либо данные. И эти данные, которые нужны для работы функции указываются в круглых скобках после названия функции. В нашем случае это (Pawn Other). Pawn – это тип переменной которая нужна, а Other – это ее имя. Имя можно указывать любое. В данном случае Other – это игрок пытающийся взять руну.

Так же забыл сказать про одну удобную вещь: это вывод сообщений в чат для отладки, чтобы отлавливать какие-либо баги. Для этого есть специальные функции:

1) slog("MY TEXT"); 
2) BroadcastMessage("MY TEXT");
3) Pawn.ClientMessage("MY TEXT");

Все эти функции похожи, но для дебага лучше использовать первую. Пример: при поднятии будет выводиться сообщение в чат:

========================== СКИПНУТЬ МОЖНО ДО СЮДА ==========================

Сразу хочу кое-что заявить: те кто писал код руны – козлы =) 
Они достаточно кривожопо всё сделали и, зачастую, дают совсем не очевидные названия переменным и функциям.

Так что давайте переименуем наш входной параметр Other на player во всех трех местах в нашей функции:

Итак, теперь нам осталось всего лишь изменить сам эффект руны. Заходим в RuneOfHealth, находим функцию PickupFunction и полностью копируем к нам в класс, заодно удалив все что было в ней кроме последней строчки Destroy();

Наша задача добавить в эту функцию подкидывание игрока. Как мы уже узнали игрок в данном случае это Other. Тогда закономерный вопрос – как нам его подкинуть вверх? Для этого нужно найти функцию внутри игрока, которая отвечает за толчок обьекта и вызвать ее в нашей функции (PickupFunction). Конечно, ты можешь пойти перелапачивать класс Pawn, Actor и др, но я облегчу твои страдания и подскажу: это функция называется AddVelocity и находится внутри Pawn. Чтобы ее вызвать просто добавляем такую строчку вначало PickupFunction:

            Other.AddVelocity(vect(0,0,1000));

Other – это тот у кого мы вызываем функцию
AddVelocity – сама функция
А то что в скобках – это мы передаем силу толчка и направление.

Слово vect – указывает что мы создаем новый вектор (который нужен функции AddVelocity). А в скобках после него – какой именно вектор. Три цифры – это три координаты. X, Y, Z. Соответственно Z – это направление вверх. И чем больше мы его поставим, тем выше подлетит игрок.

Можно было бы сказать что всё, теперь то всё должно работать, но увы нет. Если запустить – то игрок не сможет подлететь вверх (но другие направления будут немного работать). Это происходит потому, что у обьектов в определенное время стоит разное состояние физики. Для летящих обьектов – одно, для падающих – другое, для ходищих по земле – третье и тд. Так что давай зададим нашему игроку нужное состояние, а именно состояние падения. Для этого добавим следующую строчку:

Other.SetPhysics(PHYS_Falling);

Итого итоговый вид скрипта будет следующий:

Теперь можно скомпилить скрипты (F7) и протестировать.

Конграт! Теперь ты понял общий подход к программированию своих модов для руны, который использую конкретно я.

В целом можно писать скрипты в отдельных файлах, редактировать через какой-нибудь блокнот, компилировать через специальный .bat файлик и тд. Но лично я использую подход показанный выше в туториале.

Так же пара комментариев напоследок:

  1. То, что работало у тебя при тестах не факт что будет работать в сетевой игре. Так как есть такое понятие как рефлексия, которое не рассматривалось в данной статье.

  2. Если ты знаешь, что примерно искать, то внутри скрипта можно нажать Ctrl + F и ввести слово для поиска. ВАЖНО: чтобы поиск был полным, тебе нужно поставить указатель в тексте на самый вверх, так как поиск ведется от него.

  3. К сожалению, не все хоткеи работают корректно. Например, хоткей Ctrl + X иногда жестко тупит.

  4. Вроде за весь туториал написали 5 строчек кода, а я ппц устал =) Но надеюсь хоть кому-нибудь это пригодится.
  5. Возможно, напишу еще какие-нибудь туторы по кодингу для руны. Зависит чисто от настроения.

Автор: Olaf_The_Connun

Категория: Runeed | Добавил: sandsteppe (14.03.2022)
Просмотров: 52 | Комментарии: 1 | Рейтинг: 5.0/3
Всего комментариев: 1
avatar
0
1 Frenk • 15:33, 17.03.2022
https://www.youtube.com/watch?v=MAreDsQggRg
Демонстрация того, как создать (вызвать руну, который мы создали в скриптах) и как она работает
avatar