Главная
Новости
Статьи
Ссылки
Гостевая книга
Форум
Почта:
Прочее
Общая информация
Скачать
Инструменты
Авторы проекта
Глоссарий объектов

Статьи по Spirit of Half-Life

Система локусов и calc-энтити

Автор: BUzer

Пожалуй, начну издалека.
Как вы знаете, прежде чем какая-нибудь последовательность триггеров сработает, для этого должно что-нибудь произойти. Список условий довольно широк — кто-то нажал на кнопку, кто-то зашел в некую область, что-то упало на землю, или захлопнулась дверь, да и вообще — мало ли что может послужить причиной. Но большинство этих действий происходят по чьей-то вине — кто-то нажимает на кнопки, ходит по областям, и хлопает дверями. Так вот, locus-энтитей (локусом), в певоначальном понимании этого термина, для некой последовательности триггеров зовётся та энтитя, которая вызвала её активацию. Странное, и весьма абстрактное понятие, не правда ли? Не трудно догадаться, что чаще всего этим самым локусом выступает сам игрок, ведь для большинства триггеров причиной для активации служат именно действия игрока. Но так не всегда — например, для событий, вызываемых trigger_multiplie, локусом может быть и некий монстр, который вошёл в его область.
Если вы работали со спиритовыми энтитями, то, наверное, часто замечали поля, помеченные чем-то вроде [LE]. Наличие такой и подобных ей меток в названии поля обозначает, что вместо прямого указания имени энтити вы можете написать здесь ключевое слово "*locus", и это будет служить ссылкой на текущую locus-энтитю. Давайте взглянем на простейший пример:

Имеем кнопку, активирующую env_explosion. В Спирите у env_explosion есть новое поле под именем "Initial position [LP]", обозначающее место, где произойдёт взрыв. Как показывает нам наличие метки [LP], этим местом может быть и локус. Давайте впишем сюда ключевое слово *locus. Вот и всё, теперь можно запускать и смотреть, что получилось. При нажатии игроком этой кнопки, она сообщает триггеру env_explosion, кто её нажал, и взрыв происходит прямо на месте игрока, где бы он не стоял. Если дело происходит в мультиплеере, то взорвется, естественно, именно тот игрок, который нажимал кнопку.

Думаю, основную суть вы уловили. К слову, концепция локусов использовалась и в оригинальном Half-life — например, в trigger_camera, которая действовала всегда на ее локуса (это можно заметить в мультиплеере). Надо сказать, такая логика камеры в ранних версиях Халфы вызывала вылет с ошибкой "Host error..", когда к активации камеры игрок никакого отношения не имел, и она вызывалась с помощью trigger_auto.

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

Когда вы активируете какой-то триггер, то вы можете сами указать, какую энтитю он будет использовать в качестве локуса, путём дописывания её имени в скобках сразу после имени триггера. Таким образом, можно слегка доработать наш предыдущий пример — ставим три объекта info_target, и называем их как-нибудь по-разному, и вместо одной кнопки ставим три, которые активируют один и тот же env_explosion, но передают ему разные имена info_target'ов. Получается, что при нажатии разных кнопок взрыв происходит в разных местах. Конечно, для этого и не обязательно было бы использовать локусы, когда можно просто поставить три разных взрыва, но в качестве примера это вполне сойдёт. Этот способ, кстати, довольно сильно напоминает вызов некой функции в компьютерной программе с нужным аргументом.

И наконец, самым полезным в locus-системе является то, что многие триггеры, при активации чего-то, могут передавать при этом некий специальный локус. При этом в названии поля, где запрашивается имя, в конце в скобках написано, что именно будет являться локусом для вызванного события (например, название поля "Fire on collision (locus = shot)" у env_shоoter'а говорит о том, что для триггера, имя которого будет в этом поле, локусом послужит объект, которым выстрелит енв_шутер). Приведем пример использования этой штуки:

Имеем env_shooter, env_exsplosion, multi_manager, trigger_relay, и что-либо, активирующее env_shooter (в данном случае, не суть важно). Настравиваем енв_шутер, чтобы он выстреливал любую понравившуюся вам модель в нужном вам направлении (например, модель гранаты или банки из-под колы). Настраиваем env_explosion, чтобы он, как в предыдущих примерах, взрывал локус, ставим флаг "repeatable". В свойствах trigger_relay в поле "kill target" также пишем *locus. Заходим в мультименеджер, и заставляем его через три секунды активировать взрыв и реле одновременно, ставим ему флаг "Multi-threaded", а затем пишем имя этого мультименеджера в поле "Fire on spawn (locus = shot)" у env_shooter'а.
В итоге получается такая штука — после того, как шутер выстрелит модель, через три секунды она взорвется, калеча всех в округе, и, соответственно, исченет.

В конце статьи я приложу карту, где будет показано, как сделать управляемую пушку, стреляющую такими же взрывающимися банками (env_shooter тут тоже замешан :) )

В итоге, способ примерения Locus-системы и её возможностей зависит, в основном, от энтитей, которые вы используете, а точнее, насколько в этих энтитях это предусмотрено. Теперь, после получения представлений об этой системе, давайте постепенно переходить к "калькам" — calc_энтитям. Но для начала разберём, чем отличаются метки [LE], [LP], [LV], и [LR].


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

  • [LE] — Locus Entity. Cтавится в тех специфичных случаях, где триггер использует не какое-то свойство объекта, типа положения или скорости, а его самого. Например, монстр, на которого действует сценарий. Или объект, режим отображения которого меняется env_render'ом.
  • [LP] — Locus Position. Обозначает, что будут использоваться координаты энтити, а точнее, её центра. Для брашевых энтить этим центром является origin-браш. Например, координаты ипользует env_explosion, или же env_shooter.
    Имейте ввиду, что центрами монстров, как правило, являются их ступни. Если вам нужны координаты, скажем, головы, то читайте дальше, про "кальки".
  • [LV] — Locus Vector. — вектор энтити, хранимый игрой в виде трёх его составляющих по каждой оси, который является либо вектором скорости перемещения ентити, либо вектором направления её взгляда или угла (длина таких векторов единична). Используется, как правило, там, где надо или задать новые скорости или направления, или задать смещение относительно чего-то. Длина вектора скорости перемещения объекта обозначает расстояние, которое она проходит за 0,1 секунды (вроде как).
    Например, указание вектора можно использовать в env_shooter'е, как скорость и направление вылетающих моделей, или в env_laser'е, как направление луча. Вообще, применений много — просто изучайте энтити, смотрите, что можно чем задать, и как использовать.
  • [LR] — Locus Ratio. Концепция использования этого, не часто встречающегося, свойства не сильно проработана в Спирите, однако всё-равно оно может предсталять довольно интересные возможности. Вобщем, ratio — это процент. Ста процентам соответствует значение единицы, пятидесяти — 0,5 и т.д. Есть довольно мало объектов, обладающих этим параметром. Во-первых, это momentary_энтити. Для таких дверей, ratio обозначает степень, на которую они открыты (100% — открыто, 0% — закрыто, 50% — соответственно, открыто наполовину). Далее, этим свойством обладают подзаряжалки здоровья и брони — здесь 100% ratio обозначает заполненную подзаряжалку, а 0% — пустую. И наконец, для монстров и игрока ratio может обозначать его здоровье. 100% — когда монстр полностью здоров, и 0% — когда он труп.
    Использовать ratio можно как множитель — например, с помощью калек можно сделать так, что крутя momentary_кнопку, вы будете менять длину некоего вектора, от которого, например, зависит чья-то скорость.
    Присвоить ratio можно только momentary_door, и делается это, как ни странно, с помощью trigger_relay. В поле target пишете имя такой двери, в поле "Trigger to send" ставим "Ratio", и в "Set ratio" пишем цифру от нуля до единицы (единица — сто процентов). Приведу свой вполне играбельный пример двери, которая открывается, когда к ней подходишь, и остается открытой, пока ты не отойдешь. (такую штуку я использовал на своей карте, но к сожалению, она не годится для мультиплеера):

    Рисуем блок с текстурой aaatrigger, который будет обозначать область, куда должен встать и стоять игрок, чтобы дверь открылась. Делаем его trigger_inout (это новая спиритовая энтитя, вызывающая что-то одно, когда в неё входят, и что-то другое, когда из неё выходят). Ставим два trigger_relay, и у обоих в поле target пишем имя двери, и в поле trigger to send — ratio. Далее, одного из них называем "dr_open", и в поле Set ratio ставим единицу, а другого называем "dr_close", и Set ratio ставим 0. Теперь осталось только зайти в свойства trigger_inout, и в поле "Fire on entering" прописать "dr_open", а в поле "Fire on leaving" — "dr_close".
    Причина по которой тут вместо стандратной двери используется momentary_door заключается в том, что последняя может, например, не до конца закрывшись, начать открываться.

    В приложенной в конце статьи карте вы найдёте демонстрацию обоих методов использования ratio.


Уфх, вот, вроде, со всеми метками и закончили, теперь наконец-то приступим к этим "калькам", о которых я так долго трындел :)


calc_энтити нужны для того, чтобы модифицировать передаваемые триггерам значения свойств position, vector, и ratio. Используются они таким образом: в полях, помеченных [LP], [LV], или [LR] вы пишете имя соответствующей этому типу данных calc_энтити, в свойствах которой уже задаете, как именно будет расчитываться значение. Ну давайте по порядку:

  • calc_position. Прменяется с полями, помеченными [LP]. Используется в тех ситуациях, когда надо получить координаты головы, глаз, живота, или какой-нибудь точки аттачмента. Пример вы видели в Point of view, где один алиен слейв держал в руке спрайт. В Спирите такое реализуется через motion_manager, который прикрепляет спрайт к позиции, которую расчитывает calc_position, используя одну из точек аттачмента модели.
    • Entity to use [LE] — здесь вы пишете имя монстра
    • Position to calculate — а здесь указываете нужную часть его тела.
    • Add offset [LV] — если задано, то полученная точка смещается на этот вектор. В принципе, можно эту кальку использовать и в таких целях.
  • calc_subvelocity. Применяется с полями, помеченными [LV]. Используется, когда надо получить вектор, базирующийся на какой-нибудь характеристике монстра или энтити, такой, как скорость, направление взгляда, угол и т.п.
    • Value to calculate from — выбираете нужную вам характеристику.
    • Scale factor [LR] — позволяет указать множитель длины вектора.
    • Флаг "Normalize" нужен, если вам нужен вектор, указывающий направление, т.е. единичной длины.
  • calc_velocity_path. Применяется с полями, помеченными [LV]. Позволяет получить вектор, идущий от одной энтити к другой, который может использоваться, как, например, направление движения для первой энтити, если она стремится ко второй.
    • Start position [LP] — начало вектора.
    • Destination — вектор или координаты конца, в зависимости от значения следующего поля:
    • Destination is — при значении "Position" подразумевает, что в предыдущем поле вы задали имя энтити, координаты которой будут использованы как конец вектора. При значении "Offset" подразумевает задание вектора-смещения от начальной позиции.
    • Length Calculation — различные математические операции над полученным вектором. Я не сильный математик и не слишом понимаю, как их можно использовать :)
    • Line is blocked by — можете выбрать, будут ли учитываться столкновения об стены, монстров и энтити при расчёте вектора от начальной позиии до конечной. Кстати, так, наверное, можно найти вектор от энтити до ближайшей стены... круто.
  • calc_velocity_polar. Тоже работает с векторами, т.е. с полями [LV]. Используется, чтобы совершать некие математические операции над имеемым вектором, типа его вращения на определенный угол, умножения, и т.п.
    • Based on velocity [LV] — начальный вектор.
    • Rotated by angle (Y Z X) — углы, на которые надо повернуть вектор. Типа pitch, yaw, и roll.
  • calc_ratio. работает с полями, помеченными [LR]. Совершаемые функции похожи на функции предыдущей кальки — математические расчеты с имеемым значением процентности.
    • Based on ratio [LR] — начальное значение ratio (от 0 до 1)
    • Transformation — математические операции, позволяющие отразить значение ratio.
    • If outside range — если в результате операций оно стало ниже нуля или больше единицы, то это поле определяет, что с ним делать. Позволю себе процитироать документацию...
      цитата:
      Pick nearest value: e.g. if the range were 0%-100%, and the value were 120%, the result would be 100%.
      Wrap around: In the case above, the result would be 20%.
      Bounce back: In the case above, the result would be 80%.

    • с остальными параметрами типа scale или offset мы уже встречались.

Ну вот и всё пока что! Наверное, в следующий раз напишу про что-нибудь, вроде спиритового мультименеджера :\
Надеюсь, эта статья дала вам пищу для размышлений о том, как вопротить ваши идеи! А вот и обещанная карта — там пушка, стреляющая банками, супер-дверь (:)), управляемая машинка (правда она сквозь стены ездит, и приборная панель месте с ней не вращается, но зато она хорошо демонстрирует ипользование ratio и "калек"), и бонус — дымящийся func_pushable :) Запускать, естественно, под Спирит :\

PS: если что, простите за опечатки и огрехи, просто поздновато тут уже.

Вот карта: demomap_for_spirit_of_h-l.zip — zip архив на 75 кб.






Half-life Red Alert Expantion
Presented by BUzer
All rights reserved
  Counter.CO.KZ -     !
Hosted by uCoz