ПОСТРОЕНИЕ СКРИПТОВЫХ СЦЕН, Основы написания Cutscene |
Здравствуйте, гость ( Вход | Регистрация )
ПОСТРОЕНИЕ СКРИПТОВЫХ СЦЕН, Основы написания Cutscene |
May 9 2004, 14:27
Сообщение
#1
|
|||||||||||||||||||||||||
Миловидный Бегрюссунг Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени |
Здравствуйте, мы продолжаем знакомство с основами работы в BioWare Aurora Neverwinter Nights Toolset. В этот раз мы разберем изготовление скриптовых сценок на движке игры. ВСТУПЛЕНИЕ Давайте немного поговорим о том, как работают скриптовые команды. Это важно в том аспекте, что для успешного построения сценки, необходимо понимать то, что вы делаете и видеть в строках кода все примерные движения объектов и события. Звучит несколько странно, похоже на фильм “Матрица” где, глядя на экран мониторов, их герои видели код и понимали то, что он представляет, вместо ползущих цифр по экрану. Но построить сценку, не понимая что происходит, а только наугад невозможно. В скриптовых роликах основная задача вас, как режиссера, поставить все команды, из которых состоит ваш ролик в строгую последовательность, и задать жесткие временные рамки их исполнения. Больше всего времени при построении скриптовых сцен уходит на доводку исполнения той или иной команды в секундах и долях секунды. Поэтому изготовлять сам скрипт и тестить его, я рекомендую в отдельном, модуле. Так вот, что бы понять, как объект запоминает ту или иную команду, просто представьте, что у него есть специальный стек, в котором помещаются в очереди 75 команд. Цифра 75 критичный предел, больше NPC не запомнит за один раз. Для того, что бы построить сценку с командами, превышающими эту цифру, надо писать скрипт с задержкой исполнения команд. Но об этом чуть позже. Ну что, начнем? ФУНКЦИИ Наверняка вы уже смотрели в редакторе скриптов огромный список функций. Разберем основное различие между ActionSpeakString и SpeakString. Я специально выбрал эти две функции, которые выполняют одну и ту же задачу, только разными путями. На этом примере вы поймете, в чем их функциональное отличие. Например, у нас задача подойти к объекту и во время движения произнести фразу: Пример 1. ActionMoveToObject(oWp); ActionSpeakString(“Произнесенная фраза”); Наш объект, получив такую задачу, выполнит две команды по очереди. Эти команды будут загружены в его стек-команд в той последовательности, что вы видите. На деле мы получим вид: объект подошел, произнес фразу. А если нам надо во время пути, произнести фразу? Тогда мы воспользуемся функцией типа void(): Пример 2. ActionMoveToObject(oWp); ActionWait (3.0); SpeakString(“Произнесенная фраза”); Теперь наш объект, направляясь в точку oWp, во время следования (если она далеко) через три секунды произнесет фразу. Но не все функции имеют два вида, поэтому существует способ ставить команды типа void() в стек команд: Пример 3. ActionMoveToObject(oWp); ActionDoCommand(SpeakString(“Произнесенная фраза”)); В итоге получаем, что пример один равен по функциональности примеру три. ПРОСТЫЕ СЦЕНКИ Я классифицировал сцены по сложности. Это не значит, что они в реальности существуют в таком виде, просто нам так будет легче разобраться. Вот код скрипта полностью (смотри модуль).
Этот скрипт обязательно ставится на триггер, или на вход в локацию и т.д. И все действия поставлены в строгую очередь на стеке этого объекта, в данном случае триггера. Убедительно прошу не ставить скрипты роликов на OnEnter стартовой локации при начале модуля! Если у вас большая необходимость в этом, то просто напишите задержку на несколько секунд для выполнения вашей скриптовой сценки. Дело в том, что при старте модуля движок игры выполняет внутренние команды необходимые для старта и ваш скрипт пройдет при неуправляемой камере, которая упрется в пол или еще куда. Вернемся к нашему скрипту. Вы заметили, что с точки зрения программирования я его написал неверно? Точнее он перегружен лишними функциями. Это верно, но я хочу, что бы вы поняли, почему я это сделал. ActionDoCommand() в нашем случае, ставит все остальные команды в очередь стека триггера. В противном случае, все наши команды мгновенно ушли бы по адресам: игроку, NPC, и они выполнили все это в той последовательности что получили. Но мы сделали так, что триггер запомнил все нужные действия для каждого объекта у себя и просто раздал их каждому в нужный момент. Этим мы освободили себя от ненужного отслеживания выполнения команд каждым участником сценки. Попросту, мы сделали триггер нашим командиром. И в этом случае, выполнение команд можно просто отделить друг от друга командой ActionWait() для триггера. Я советую не уничтожать вам этот триггер в конце, как делают многие, так как он может уничтожиться раньше завершения акций и ваш ролик не успеет завершиться. Советую NPC при таких сценках уже готового из синьки ставить в закрытую локацию, специально изготовленную для таких нужд. Дело в том, что при одиночной игре при команде CreateObject() компьютер ваш будет немного тормозить. Это связано с тем, что в случае одиночной игры он и сервер и клиент одновременно. Поэтому на вашей супер тачке Р-IV 3000 и мозгами 1 Гб может виден слегка заметное подергивание. И чем больше вы создаете объектов, тем больше тормозов. Для шардов это не актуально, у них клиент и сервер на разных машинах. Разберем некоторые части скрипта подробно.
Этот строчка не даст запускаться скрипту если на триггер наступил не РС или скрипт уже один раз сработал. SetCutsceneMode(oPC); Переводит РС в режим сцены, убирает панель и делает его недоступным для управления игроком.
Эта строчка поворачивает оРС в сторону, в данном случае лицом на дверь из которой появится NPC. Команда SetCameraFacing() установит камеру в то положение, которое вам нужно для комфортного просмотра вашей сценки. Я разберу на примере параметров нашего скрипта: CAMERA_TRANSITION_TYPE_SNAP немедленно переместит камеру на новую позицию, тогда как другие типы, перемещают постепенно в позицию. CAMERA_TRANSITION_TYPE_MEDIUM - переместит камеру в то положение, которое мы укажем из исходного. 250.0 - градусы относительно оси. (0.0f=East, 90.0f=North, 180.0f=West, 270.0f=South) начертите на бумаге схему с градусами и сторонами света, вам будет удобнее ориентироваться. 20.0 удаление от игрока. (Мин 5 мах 20) 45.0 наклон (1 - вертикально, 50.0 мах почти в горизонт)
Это наша дама выкрикнет приветствие. Запомните, что это будет действовать, только если установлен звук у NPC с такой возможностью. Этого звука нет у монстров и прочих неважных NPC. Такие звуки есть у стандартных комплексов звуков РС или хеньчманов. Так что если вы примените PlayVoiceChat() и у вас не будет звука в скрипте, просто смените у NPC набор звуков в свойствах. Но стоит знать одну особенность стандартных скриптов от BioWare. Если вы пользуетесь PlayVoiceChat(), то параллельно звуку будет SpeakString() фразы из скриптов по умолчанию. Что бы не появлялись английские фразы в сценке надо поставить следом за функцией PlayVoiceChat() строку с какой-нибудь фразой из сценки, причем время срабатывания должно быть одно и то же, и лишь порядок функций должен быть такой: звук и сразу фраза. Мы просто накладываем одну строку сразу на другую, скрывая иностранные буквы и фразы.
Снимает режим скриптовых сцен у РС. Сделайте одну две НЕЙТРАЛЬНУЮ КО ВСЕМ фракцию, специально для SetCutsceneMod(). Дело в том, что врагов РС трудно будет заставить не убивать вас, а если у него будет нейтральная фракция, то можно ее сменить прямо в скрипте с одной на другую. Но об этом позже. Я не затрагивал такие параметры, как поведение хеньчмана, фамильяра и т.д. На такую короткую сценку можно, например, просто поставить дополнительную точку и ставить их туда. Сценка короткая и сбоев из-за свободы помощников быть не должно. Как управлять камерой и РС при перемещении сценки и другие сложные вопросы мы рассмотрим ниже. СЛОЖНЫЕ СЦЕНКИ В понятие “Сложные”, я вкладываю управление игроком при перемещении, обработку помощников и использование команд больше чем может вместить стек одного объекта. К тому же вам, наверное, хотелось бы переместить камеру и показать с разных ракурсов одну и ту же сцену. Спешу сразу вас разочаровать, “Aurora Engine” не позволяет отрывать камеру от игрока, но это не повод для того, что бы ни пользоваться перемещением камеры. Реализуется это следующим образом: делаем затухание экрана, на игрока накладываем невидимость, перемещаем его в нужную точку с нужным ракурсом, убираем затухание, пошла сценка.
Основное отличие от кода первого скрипта здесь будет наличие такой функции как DelayCommand(). Эта функция позволяет задержать выполнение той или иной команды на требуемый отрезок времени от начала отчета, которое равно запуску скрипта. Наше построение команд тоже несколько изменится, теперь мы не будем вешать все на один объект, заполняя его стек-команд, соответственно отпала нужда в ActionDoCommand(). Лучше откройте его в Toolset-е и посмотрите скрипт в нем. Я еще объясню некоторые моменты, которые не стал комментировать в нем и важные моменты вообще о которых можно и нужно сказать отдельно. Теперь я определил спутников игрока, будь то: животное, фамильяр или хеньчман. И для того, что бы наш спутник вел себя адекватно, а вернее не мешал и не болтался под ногами, мы его просто-напросто парализовали специальным эффектом EffectCutsceneParalyze(). Теперь он точно не кинется за нами вдогонку при перемещении камеры и не станет на пути NPC. Еще один момент. Я несколько усложнил задачу в скрипте и сделал его на диалоге, который переходит в паузу и продолжается с той же строки после прохождения сценки. Для того чтобы мы взяв игрока из точки диалога могли, точно его вернуть назад, воспользуемся этой функцией:
В ней мы запомнили координаты игрока и в конце скрипта вернем его назад в исходную точку. Еще момент. Если мы хотим что бы игрок участвовал в каком то эпизоде в сценке, но перед этим он был невидим то подбираем для него время при котором он будет скрыт от нас, затем эффект заканчивается, мы его показываем, после опять накладываем эффект невидимости и т.д. Все это естественно с затуханием экрана, или если у вас свои планы то не делайте. Тут выбор за вами.
Этой строкой мы сделали AI у нашего NPC высоким, для того, что бы он лучше искал путь до нужного объекта, пользовался разными зельями в общем, что бы не “тупил”. Однако это сильно нагружает систему, ведь по умолчанию стоит AI_LEVEL_DEFAULT. После того, как пройдет сценка, верните этот параметр на место, если вы не уничтожаете NPC.
В игре нет возможности заставить игрока идти к цели, а не бежать. Если мы можем отправить NPC пешком, то игрока мы можем заставить идти только при помощи такого эффекта. Иногда, для того, что бы показать появление NPC, не обязательно его брать из закрытой локации или создавать скриптом. Можно просто поставить его в нужную точку или в укромное место и при запуске скрипта сделать его невидимым несколько секунд и снять эффект когда нужно. Он как бы появился из неоткуда, а сам на самом деле, будет стоять все это время парализованный и невидимый за рядышком. Я этим очень часто пользуюсь, чего советую и вам. Так как наши участники сценки все с одной или двумя нейтральными фракциями, то изменить в конце нашего ролика фракцию можно командой:
Если необходима другая фракция, не стандартная, то это тоже можно сделать
(смотрите функции). ЗАКЛЮЧЕНИЕ Я хотел написать еще одну сценку, но потом подумал, что вам будет интересней увидеть не бутафорскую, а настоящую сцену. Так вот, я выкладываю вместе с модулем скрипт финальной сцены в модуле “Проклятие Левора – Пламя Флегетоса”. Это третий модуль первой части нашей команды, его можно взять с диска журнала “Навигатор Игрового Мира” за июнь месяц или с нашего сайта www.wrg.ru. Просто сделайте экспорт этого скрипта в модуль и посмотрите, какой объект что делает и как себя ведет. Я сделал необходимые комментарии, поэтому если вы разобрались с первыми двумя скриптами, то этот поймете без проблем. Не гарантирую, что в той версии модуля, которая в журнале, он будет работать как часы, так как я его дорабатывал, но для вас главное будет посмотреть код. Код скриптов, что я вам привожу, не обременен дополнительными условиями. Например, можно присвоить переменную и при наличии таковой сделать разные фразы или финал сценки. Но все это уже на ваше личное усмотрение. Моя задача научить вас азам.
ПРОДОЛЖЕНИЕ СКРИПТА СМОТРИТЕ В МОДУЛЕ!
Прикрепленные файлы
|
||||||||||||||||||||||||
May 12 2004, 20:54
Сообщение
#2
|
|
Level 8 Класс: Псионик Характер: Chaotic Good Раса: Человек NWN: Скриптинг [Sn] |
Aiwan, могу выложить базу, ЗНАЧИТЕЛЬНО облегчающую создания катсцен (IMG:style_emoticons/kolobok_light/good.gif) . Команды НАМНОГО проще в обращнии, чем *официальные*. По крайней мере мне этот инлюд сэкономил достаточно много времени.
|
May 12 2004, 21:40
Сообщение
#3
|
|
Level 11 Класс: Обыватель Характер: True Neutral Раса: Человек NWN: Маппинг |
Tarre, выложи плиз! (IMG:style_emoticons/kolobok_light/smile.gif)
|
May 12 2004, 23:40
Сообщение
#4
|
|
Миловидный Бегрюссунг Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени |
// Tarre я не понял, ты чего старый ник не юзаешь?
Выложи в тему скриптов. (IMG:style_emoticons/kolobok_light/wink3.gif) |
May 13 2004, 13:09
Сообщение
#5
|
|
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
Тарре, выкладывай сюда, а не в скрипты. (IMG:style_emoticons/kolobok_light/smile.gif) Айв, тебе чем не нравится, чтобы здесь лежало? Все по теме. К тому же с удовольствием гляну этот инклюд...
|
May 13 2004, 15:12
Сообщение
#6
|
|||
Level 8 Класс: Псионик Характер: Chaotic Good Раса: Человек NWN: Скриптинг [Sn] |
Сам инклюд
Если надо, могу выложить более подробное объяснение. Но, думаю, и так все ясно. ЗЫ: зацените GestaltCameraMove() - шедевр (IMG:style_emoticons/kolobok_light/biggrin.gif) |
||
May 13 2004, 16:40
Сообщение
#7
|
|
Level 11 Класс: Обыватель Характер: True Neutral Раса: Человек NWN: Маппинг |
Большое спасибо! (IMG:style_emoticons/kolobok_light/smile.gif)
Теперь не прийдется качать Лексикон (IMG:style_emoticons/kolobok_light/wink3.gif) |
May 13 2004, 21:38
Сообщение
#8
|
|
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
Хех, Гештальт Камера - старинный инклюд времен первого НВН. Не расчитан на Катсцены. Можете его адаптировать под них, но... имхо не имеет смысла. Я с него соскочил с появлением СоУ, где можно было сценки делать. Хех. (IMG:style_emoticons/kolobok_light/smile.gif) Я думал будет более интересное что-то... (IMG:style_emoticons/kolobok_light/sad.gif)
|
May 15 2004, 17:26
Сообщение
#9
|
|
Level 8 Класс: Псионик Характер: Chaotic Good Раса: Человек NWN: Скриптинг [Sn] |
Ну почему же не рассчитан... очень даж рассчитан. Лично МНЕ намного удобней юзать эту инлюду, чем стандартные функции. Кстати с помощью этой вещи можно реализовать фиксированную камеру(в принипе так тож можно, но нечто похожее я видел только при плавании камеры в ареи КАРТА ВАСТА Проклятия).
Цитата Я думал будет более интересное что-то Извините если что не так (IMG:style_emoticons/kolobok_light/smile.gif) ) |
May 16 2004, 02:30
Сообщение
#10
|
|
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
Да нет, Тарре, не обижайся! (IMG:style_emoticons/kolobok_light/good.gif) Извини меня, если че не так (IMG:style_emoticons/kolobok_light/wink3.gif) .
Фиксированая камера, это не что иное, как удаление с экрана героя. (IMG:style_emoticons/kolobok_light/wink3.gif) Джамп в невидимом состоянии... |
May 16 2004, 19:14
Сообщение
#11
|
|
Level 8 Класс: Псионик Характер: Chaotic Good Раса: Человек NWN: Скриптинг [Sn] |
Про фикс: я не совсем то имел ввиду.Про катсцен_инвизибл я и так знаю. Я иел ввиду, что можно релизовать такую полезнейшую вещь, как неуправляемая героем камера, причем все это не в режиме катсцены.
|
Jun 23 2004, 22:04
Сообщение
#12
|
|
Level 10 Класс: Воин Характер: Lawful Neutral Раса: Человек NWN: Скриптинг [PW] |
Вопрос назрел к Айвану.
Что то у меня неполучается чтобы при нападении камера к монстру развернулась. Код object oEnemy = GetLastAttacker(); float fEnemy=GetFacing(oEnemy); AssignCommand(oPC, SetCameraFacing(fEnemy, 5.0, 45.0, CAMERA_TRANSITION_TYPE_MEDIUM)); |
Jun 23 2004, 23:47
Сообщение
#13
|
|
Миловидный Бегрюссунг Класс: Воин Характер: Chaotic Good Раса: Человек NWN: Модмейкер Проклятие Левора Порядок Времени |
Ну ты даешь! (IMG:style_emoticons/kolobok_light/shok.gif) У РС куча забот а ты его еще камерой мутузишь! (IMG:style_emoticons/kolobok_light/lol.gif)
Код vector vD = GetPosition(oEnemy) - GetPosition(oPC); float fEnemy = VectorToAngle(vD); AssignCommand(oPC, SetCameraFacing(fEnemy, 5.0, 45.0, CAMERA_TRANSITION_TYPE_MEDIUM)); Не подумай что я такой умный (IMG:style_emoticons/kolobok_light/unsure.gif) это код ДБа. Просто я знаю где он и как работает (IMG:style_emoticons/kolobok_light/biggrin.gif) |
Jun 24 2004, 02:57
Сообщение
#14
|
|
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
Кстати спецы по векторам у нас Лекс и Баал. Так что разрулят, если возникнут вопросы (IMG:style_emoticons/kolobok_light/wink3.gif) .
LEX: не переводи на меня стрелки, ДБ. Я не шарю в векторах. Ты и Баал, вот, кто шарят. |
Jul 9 2004, 00:07
Сообщение
#15
|
|
Level 10 Класс: Воин Характер: Lawful Neutral Раса: Человек NWN: Скриптинг [PW] |
Интересный вопросик.
У нас есть один момент - заходишь в локацию. На игрока накладывается СетКутСценеМод=Трю, потом эффект - КутСценИнвизибл. Тоесть как бы началась сценка и игрока не видно, видно только НеПиСей. Так вот стоит нажать Esc как игрок появляется и появляется панель управления игрока(HUD). И во время кутсцены игрок уже может ходить вокруг "отыгрывающих" НПС. Пробовал наложить на него СетКоммандэйбл(Фолс, оПС). Но это ничего не поненяло - жм у Esc игрок появляется, только двигатся не может. В чем дело не пойму. З.Ы. У меня НВН в окне, может из за этого?! |
Jul 9 2004, 11:52
Сообщение
#16
|
|
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
Может и из-за этого... Но скорее всего это из-за известного бага - ставить на онЭнтр локации катсцену нельзя... (IMG:style_emoticons/kolobok_light/sad.gif) Возможны кучи багов. Лучше поставить триггер при входе в локу и на него вешать катсцену.
|
Jul 9 2004, 14:20
Сообщение
#17
|
|
Level 8 Класс: Псионик Характер: Chaotic Good Раса: Человек NWN: Скриптинг [Sn] |
Нет. Ав, тебе надо было сначала у меня спросить. Просто я в своем моде для теста (вдруг с катсценой что не так) на он_катсцен_абортед поставил снятие всех эффектов + рестор положения камеры :-)
|
Jul 12 2004, 14:15
Сообщение
#18
|
|||
Level 11 Класс: Обыватель Характер: True Neutral Раса: Человек NWN: Маппинг |
Подскажите что тут не правильно...
Что самое обидное - они не подравшись, и кстати за ними не пришел мент из комнаты, начинают бежать к двери и пропадают не добежав. А дверь открылась. (IMG:style_emoticons/kolobok_light/smile.gif) Подскажите плиз |
||
Jul 12 2004, 15:02
Сообщение
#19
|
|
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
А скрипт на чем стоит? Триггер? Лока? Еще что?..
|
Jul 12 2004, 15:32
Сообщение
#20
|
|
Level 11 Класс: Обыватель Характер: True Neutral Раса: Человек NWN: Маппинг |
Триггер OnEnter
|
Jul 12 2004, 15:45
Сообщение
#21
|
|||
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
2GoDoom Катсцены пишутся по такой схеме:
Иначе ты будешь еще долго разбираться в стеке акций... И сбои никогда неисключены. А через DelayCommand все всегда получается и быстрее, и безошибочнее. |
||
Jul 12 2004, 16:14
Сообщение
#22
|
|||
Level 11 Класс: Обыватель Характер: True Neutral Раса: Человек NWN: Маппинг |
Окей, спасибо - буду пробовать Добавлено в [mergetime]1089639537[/mergetime] Еще большие глюки (IMG:style_emoticons/kolobok_light/sad.gif) Правильно написано?:
Добавлено в [mergetime]1089639872[/mergetime] Еще что не понятно - камера то не крутится (IMG:style_emoticons/kolobok_light/sad.gif) |
||
Jul 12 2004, 17:46
Сообщение
#23
|
|
Level 8 Класс: Псионик Характер: Chaotic Good Раса: Человек NWN: Скриптинг [Sn] |
Код ActionDoCommand(SetCameraFacing(180.0, 15.0, 50.0, CAMERA_TRANSITION_TYPE_SLOW)); Неверно. Верно так: Код AssignCommand(oPC, SetCameraFacing(180.0, 15.0, 50.0, CAMERA_TRANSITION_TYPE_SLOW));
|
Jul 12 2004, 18:19
Сообщение
#24
|
|
4-х Кубовый Класс: Некромант Характер: Lawful Evil Раса: Человек NWN: Скриптинг [Sn] Проклятие Левора |
Ну вроде как все правильно. А что глючит-то? Как?
|
Jul 12 2004, 19:22
Сообщение
#25
|
|
Level 11 Класс: Обыватель Характер: True Neutral Раса: Человек NWN: Маппинг |
ну вообщем так:
Я встаю на триггер, вклчюается катсцена: Мужик перекрикиваются, очень резко поворачиваются друг на друга, затем один подбегает и стоит. Через пару секунд камера не трогается с места а мой персонаж очень резко поворачивается, затем открывается дверь, закрывается дверь, затем два дрочуна бегут к двери, из двери бежит охраник и пропадают недобегая никуда... Вот так то (IMG:style_emoticons/kolobok_light/sad.gif) |
Текстовая версия | Сейчас: 10th November 2024 - 20:50 |