Глава XIII. Деревья, решетки, кнопки, ящики.

Объекты карты: деревья, прозрачные решётки, кнопки, рычаги и ящики.

13.1

Создание деревьев

В этой статье мы расскажем о различных способах создания деревьев. Мы будем использовать следующие энтити-объекты: Создать в CS реалистичное дерево довольно трудно. Залогом успеха является подбор качественных текстур деревьев. Первый способ создания деревьев основан на применении объекта func_illusionary. Как Вы знаете, через такой объект можно свободно проходить, помимо того, если использовать текстуру с маской (с синими частями), то можно сделать эти части объекта прозрачными. Именно этими свойствами мы и воспользуемся.
На рисунке ниже представлена текстура дерева, которую мы будем использовать.
Текстура дерева
Построим браш с размерами 224 юнита в высоту, 128 юнитов в ширину и 1 юнит в толщину и разместим его перпендикулярно земле, как показано на рисунке ниже.
Создаем объект func_illusionary, окрашенный текстурой дерева
Превратим этот браш в func_illusionary и выставим следующие параметры отображения:
Render Mode — Solid;
FX Amount — 255
Благодаря таким параметрам, синие части текстуры будут в игре прозрачными, таким образом, останется только крона дерева.
Теперь скопируем func_illusionary и вставим перпендикулярно первому объекту (см. рис. ниже).
t14tree3 Таким образом, у нас поличилось довольно-таки симпатичное деревце :) Также можно добавить веточек, развернув их под углом 45° к основной кроне. Единственное, чего нам еще не хватает, так это ствола. Изготовим его при помощи инструмента Block и его функции Spike. На панели "New objects" в списке "Objects" выберем функцию Spike, укажем цифру 8 в строке "Faces" (количество боковых сторон) и построим браш в центре дерева размером 256 юнитов в высоту и 7х7 юнитов по ширине и толщине (см. рис. ниже).
Создаем ствол дерева при помощи функции Spike
Превратим ствол в func_wall, чтобы он не разбивал землю на большое количество полигонов (подробнее об этом Вы можете прочитать в главе об R_speeds). На нашей тестовой карте мы дополнительно разместили еще 4 таких дерева. Чтобы они не казались похожими друг на друга, мы повернули их под разными углами.
В игре наш небольшой сад выглядит как показано на рисунке ниже, справа:
Так выглядит наш сад в игре
На этом же рисунке, слева, Вы можете видеть другие деревья (пальмы). Сейчас мы расскажем о том, чем же они отличаются от выше описанных деревьев.
А отличие заключается в том, что пальмы не являются объектами func_illusionary с нанесенными на них текстурами деревьев. Это заранее изготовленные модели деревьев, сохраненные в файлы с расширением *.MDL. В архиве с нашей тестовой картой находится одна модель дерева (пальма). Чтобы запустить карту необходимо скопировать модель дерева в директорию cstrike/models..
А теперь собственно о том, как вставить модель дерева или любую другую модель на карту.
Для вставления моделей используется точечный энтити-объект cycler или cycler_sprite. Просто вставьте такой объект в нужном месте на карте. В свойствах необходимо указать путь к файлу *.mdl с нужной моделью. Если используется объект cycler_sprite, предназначенный вообще-то для вставки спрайтов (*.SPR), то в свойствах, там, где указывается имя модели, необходимо сначало прописать *.*, чтобы отобразить все типы файлов, а не только *.SPR. Затем выбираем нужную модель.
В нашем случае свойства объекта cycler выглядят так:
Model — models/tree_palm.mdl
Вот и все свойства.
Кстати, использовать объект cycler_sprite, возможно, даже лучше, чем cycler, т.к. в этом случае из МОДЕЛИ при стрельбе по ней не будет ВЫЛИВАТЬСЯ черно-белая кровь (иногда есть такое), как происходит, когда модель вставлена объектом cycler.
Начиная с CS 1.6, мы можем использовать модели, имеющие текстуры с маской (синие части, прозрачные в игре). Теперь деревья выглядят уже неплохо и даже могут иметь анимацию: колыхаться на ветру.
trees.zip [116Кб] — в архиве карта-пример в форматах BSP и RMF, а также необходимые модели и текстуры.
13.2

Прозрачные решетки и заборы

В этой статье мы расскажем как создаются прозрачные простреливаемые решетки, заборы и т.д. Для создания нам потребуется объект: Как Вы наверное уже знаете, прозрачные объекты закрашиваются текстурами с маской (синими частями). Названия таких текстур начинаются с фигурной скобки {. Также необходимо выставить параметры отображения:
Render Mode — Solid;
FX Amount — 255.
Ну, чтож, выберем текстуру {BARS и построим браш произвольных размеров с толщиной 4 юнита. Превратим его в func_wall. Выставим параметры отображения, как написано выше. В итоге мы получим прозрачную решетку.
Чем же она плоха? А плоха она тем, что, во-первых, не все виды оружия простреливают энтити-объекты (например, пистолеты не простреливают) и, во-вторых, на решетке остаются следы от пуль (см. рис. ниже). За решеткой мы разместили черную стенку, чтобы следы были лучше видны.
t13grate1 Вместо func_wall необходимо использовать func_illusionary . Выставим абсолютно такие же параметры отображения. Единственное, что нужно еще сделать, так это поместить перед решеткой CLIP-браш (обычный браш, со всех сторон покрашенный специальной текстурой CLIP). Это необходимо сделать, т.к. через func_illusionary игрок может свободно проходить, а CLIP-браш не даст этого сделать (см. рис. ниже). CLIP-браш обычно делают таких же размеров, как и решетка, но это не принципиально, главное, чтобы игрок не пролез :)
Перед решеткой из func_illusionary дополнительно размещаем CLIP-браш
Таким образом, через решетку из func_illusionary свободно пролетают пули и гранаты, не оставляя никаких следов, а игрок, вместе с тем, пройти через нее не может.
Если необходимо сделать разбиваемую решетку (как в вентиляционной трубе на cs_assault), то браш нужно превращать в func_breakable с Render Mode — Solid, FX Amount — 255. CLIP-браш в этом случае, естественно, не нужен.
grates.zip [11Кб] — в архиве карта-пример в форматах BSP и RMF.
13.3

Кнопки и вращающиеся рычаги

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

1. Создание кнопок

В нескольких предыдущих статьях мы уже кратко рассказывали о созданни кнопок, остановимся на них более подробно.
Кнопки используюся в основном для открытия дверей, вызова лифта и для включения/выключения света. Изначально создается браш необходимой формы, затем он превращается в объект func_button. Давайте рассмотрим случай, когда нажатие на кнопку приводит к выключению света.
Где-нибудь на стене разместим браш с размерами 10х8х2 юнита (размеры довольно маленькие, т.к. это всего лишь выключатель). Закрасим этот браш с видимой стороны анимированной текстурой с длинным названием +0FIFTSSTCH4 (см. рис. ниже). Это хорошая текстура выключателя. Когда мы нажмем на кнопку, текстура сменится, и создастся впечатление, что выключатель нажат.
Создаем кнопку
Превратим браш в объект func_button и выставим следующие свойства и флаги:
Targetted object — light1 (так будет называться источник света, который мы будем включать этой кнопкой);
Sounds — lightswitch (звук при нажатии на выключатель);
Delay before reset — 0 (время в секундах, в течении которого кнопка не работает после нажатия. В данном случае кнопку можно будет нажимать сколь угодно часто. Если поставить значение "-1", то кнопку можно будет использовать только один раз за раунд).
Флаги:
Don't move — если отмечено, то при нажатии кнопка не вдавливается в стену, а остается на месте. Очень полезный флаг, т.к. позволяет избежать необходимости выставления ряда дополнительных параметров (см. ниже);
Toggle — если отмечено, то кнопка будет оставаться в нажатом положении, пока ее снова не используют. В нашем случае, т.к. кнопка не двигается, этот флаг будет "удерживать" переключившуюся текстуру. В таком случае текстура будет меняться один раз при каждом нажатии
Теперь рассмотрим остальные возможные параметры кнопки.
Angle — направление, в котором двигается кнопка при нажатии, задается в градусах. Мы рекомендуем определять направление на виде сверху, т.к. это удобнее всего;
Speed — скорость, с которой кнопка будет вдавливаться в стену (если установлен флаг "Don't move", то этот параметр бесполезен);
Health — "жизни" кнопки. Если Вы хотите, чтобы кнопку можно было нажать выстрелом, то установите здесь значение больше 0, например, 1;
Delay before trigger — время в секундах, которое пройдет после нажатия на кнопку и активацией объекта, указанного в параметре "Targetted object". Например, если указать здесь значение 5, то свет включится только через 5 секунд после нажатия кнопки;
Lip — этим параметром можно изменить расстояние, на которое кнопка вдавливается в стену. По умолчанию кнопка нажимается на расстояние своей толщины, таким образом, она как бы скрывается в стене в нажатом положении. Если Lip положительный (Lip измеряется в юнитах), то кнопка "проедет" меньшее расстояние, а если отрицательный — большее.
Подробнее об определении Lip Вы можете прочитать в статье "Сдвигающиеся и вращающиеся двери".
Также у кнопок есть редко используемые флаги "Sparks" и "Touch Activates". Если отмечен первый, то из кнопки будут сыпать искры, если второй — то кнопка будет нажиматься от простого прикосновения игрока (не надо нажимать кнопку "Use").
Со свойствами разобрались.
На тестовой карте мы разместили два объекта light с одинаковыми именами light1 (это имя мы вписали в параметр "Targetted object" кнопки). Также мы отметили у обеих лампочек флаг "Initially dark", чтобы в начале раунда они не горели.

2. Создание рычагов

Теперь рассмотрим создание вращающегося рычага. Помните рычаг в подземном туннеле на cs_militia, который выключает свет? Сейчас мы расскажем как сделать такой же. В нашем примере рычаг будет открывать дверь (объект func_door), которая ведет из комнаты на улицу.
На рисунке ниже Вы можете видеть очень простой рычаг, состоящий всего из одного браша (вертикальная "палка"). Все остальные браши (большая коробка и небольшой браш на ее боковой стороне) сделаны для большей реалистичности. Так как рычаг в данном случае вращающийся объект, то для него необходимо определить ось вращения. Как Вы уже знаете, точка в пространстве, через которую проходит ось вращения определяется центром ORIGIN-браша.
Создаем рычаг и ось вращения (ORIGIN-браш)
На рисунке ниже видно как размещен ORIGIN-браш. Для наглядности мы удлиннили его вдоль оси вращения (это горизонтальная ось).
Размещение ORIGIN-браша
Теперь выделим "палку" и ORIGIN-браш и превратим их в func_rot_button. Затем выставим следующие свойства и флаги (относится к рычагу, используемому в нашей тестовой карте):
Targetted object — door1 (так будет называться дверь, которую будет открывать рычаг);
Speed — 200 (скорость вращения рычага, в данном случае довольно высокая);
Sounds — gus clunc (звук при нажатии на рычаг, есть несколько вариантов, выбирайте любой);
Delay before reset — 0 (время в секундах, в течении которого рычаг не работает после нажатия. В данном случае рычаг можно будет нажимать сколь угодно часто. Если поставить значение "-1", то рычаг можно будет использовать только один раз за раунд);
Distance (deg) — 180 (угол, на который повернется рычаг при движении. В нашем случае рычаг остановится в нижнем вертикальном положении).
Флаги:
Not Solid — желательно, чтобы Вы всегда отмечали этот флаг. Он делает рычаг нематериальным. Такой рычаг не задевает игроков при вращении и наооборот, игроки не мешают вращаться рычагу. Если рычаг довольно длинный и этот флаг не отмечен, то может возникнуть ситуация, когда рычаг будет задевать игрока, нажимающего его, и, соответственно, не будет вращаться;
Reverse Dir — этот флаг заставляет рычаг вращаться против часовой стрелки. Направление легко определить на виде сверху: если конец рычага перемещается справа налево в верхней позиции рычага, то это движение против часовой стрелки и наоборот. Флаг полезно отметить в том случае, когда рычаг при своем вращении проходит сквозь стену, чего по идее не должно быть;
Toggle — если отмечено, то рычаг после активации будет оставаться в нажатом положении, пока его снова не активируют;
Y Axis — в нашем примере ось вращения рычага на виде сверху проходит вертикально, следовательно это ось Y. Если ось на виде сверху проходит горизонтально, то следует отмечать флаг "X Axis". Естественно, если рычаг вращается вокруг оси Z, то никаких флагов отмечать не надо.
Рычаг готов. Остается лишь создать дверь с именем door1, чтобы проверить работу рычага.
Как всегда, если что-то для Вас осталось непонятным, Вы можете скачать карту-пример и разобраться во всем самостоятельно при помощи исходников.
buttons.zip [30Кб] — в архиве карта-пример в форматах BSP и RMF.
13.4

Все о ящиках

Из этой статьи Вы узнаете, как сделать, чтобы ящики взрывались вместе с бомбой, почему некоторые мапперы поднимают ящики над землей, как сделать непростреливаемый ящик, как решить проблему с двумя, стоящими друг на друге разбиваемыми ящиками, а также некоторую другую полезную информацию.
Итак, ящики или crates по-английски. Ящики стали неотъемлемой частью карт в Counter-Strike. Они используются как укрытия в местах стычек команд, их устанавливают на бомб-плейсах, их используют для того, чтобы забраться в недоступные места и т.д. Трудно найти карту, чтобы на ней не было ящиков. А, например, такая карта как DE_DUST2 вообще, наверное, является чемпионом по количеству ящиков :) Если Вы вспомните карту DE_SURVIVOR (снежная такая), то на ней Вы найдете всего 1 ящик, на котором с насмешкой написано: "Это единственный ящик на всей карте!" Так решил пошутить автор карты — 3D_Mike.
Оставим на его совести ящики на одном из бомб-плейсов, на том, где стоит грузовик. Хотя сам Майк называет их не ящиками, а коробками... Ах, ну да! Большая разница... — в общем, ящики используют практически все мапперы.

1. Взрываем ящики вместе с бомбой

Все мы прекрасно помним как на карте DE_DUST вместе с бомбой взрываются ящики. Давайте посмотрим, как реализована данная фишка. На картинке ниже изображена схема, при которой ящики взорвутся вместе с бомбой.
При таких свойствах объектов, ящики взрываются вместе с бомбой
Итак, у нас есть объект func_bomb_target, закрашенный спецтекстурой AAATrigger. Этот объект, как Вы знаете, определяет место закладки бомбы. Еще у нас есть несколько ящиков (пока что это обычные браши). Все эти ящики необходимо превратить в объект func_breakable (выделите все ящики и нажмите [Ctrl-T], в списке выберите func_breakable).
Вы можете превратить каждый ящик в отдельный func_breakable, а можете все ящики разом превратить в 1 единственный func_breakable. Если Вы решите сделать несколько func_breakable, то дайте всем им одинаковое имя.
Главные свойства func_breakable:
Name — bomb_crate (обязательно укажите имя, оно может быть любым);
В закладке Flags необходимо отметить:
Only Trigger — чтобы ящики взрывались только от триггера, т.е. бомбы в нашем случае.
Остальные параметры, такие как: material type (материал), explode magnitude (мощность взрыва) - выставьте по своему усмотрению.
Теперь перейдем к объекту func_bomb_target. Все, что нужно с ним сделать, это вписать в параметр "Target (when bomb blows)" имя наших ящиков, т.е. bomb_crate. Вот и все.

2. Почему мапперы подвешивают ящики над землей

Например, на карте DE_NUKE есть такой "баг":
Ящик "парит" над землей
А багом это называют устроители различных чемпионатов по Counter-Strike. Они даже следят за игроками, чтобы те не смотрели в эту щелку, через которую видно ноги противника.
На виде сбоку это выглядит следующим образом:
t20crate1 Возможно, автор карты специально хотел сделать такую фишку, но это в данном конкретном случае, а так, обычно, ящик не доводят до земли на 1 юнит, в целях уменьшения параметра r_speeds, который показывает количество полигонов, рисуемых игровым движком. Если ящик является обычным брашем (не энтити-объектом) и соприкасается с полом, то пол будет разбит на более мелкие полигоны, что увеличит их количество, и соответственно, параметр r_speeds.
Если же ящик является энтити-объектом, например, func_wall, или же он не соприкасается с полом (как в нашем случае), то разбиения не происходит и r_speeds не повышается. Таким образом, мы можем сэкономить несколько полигонов. Подробнее об оптимизации карты и уменьшении r_speeds Вы можете прочитать в соответствующем разделе Учебника.

3. Как сделать непробиваемый ящик

Вернемся опять к карте De_Dust. На картинке ниже изображен ящик, который не пробивается ни из одного вида оружия.
"Устройство" непробиваемого ящика
Как видно из картинки, ящик разрезан на две половинки по вертикали. Движок Half-Life устроен таким образом, что один браш или энтити-объект пробиваются из пробивающих видов оружия, а два, стоящих вплотную друг к другу — нет. В этом и заключается ответ на вопрос, почему более крупные ящики, стоящие в "кишке" пробиваются, а этот, казалось бы, не очень толстый ящик — нет.
В некоторых случаях, возможно, Вам понадобится сделать два ящика стоящие рядом, и чтобы они были пробиваемыми. Тогда вместо двух ящиков необходимо создать один, но по размеру равный двум (см. рис. ниже).
Создаем "два" стоящих рядом пробиваемых ящика (браш один)
А вот как просто затекстурировать данный ящик. Выберите нужную текстуру ящика, выделите большую сторону ящика и на панели работы с текстурами (Face Properties) нажмите кнопку Fit, чтобы растянуть текстуру по всей стороне браша.
Нажимаем кнопку Fit, чтобы растянуть текстуру по всей стороне браша
Затем на той же панели уменьшите в 2 раза масштаб (Scale) текстуры по оси Х или Y (зависит от положения ящика). Если Вы решите сделать не 2 ящика, а скажем 4, то и масштаб уменьшайте в 4 раза и т.д.
Уменьшаем в 2 раза масштаб (Scale) текстуры по оси Х или Y в зависимости от положения ящика
Затем скорее всего понадобится понажимать на кнопки выравнивания по сторонам L, R, T, B, C, чтобы текстура легла ровно, как на рисунке ниже.
Выравниваем текстуру кнопками L, R, T, B, C
Игроку кажется, что ящика два, хотя на самом деле браш один. А раз браш один, значит он будет пробиваться.

4. Два разбиваемых ящика, стоящие друг на друге

На картинке ниже изображены два разбиваемых ящика, каждый из которых является отдельным объектом func_breakable.
Задача заключается в том, чтобы разбив нижний ящик, верхний также бы разрушался
Если игрок разобъет сначала верхний ящик, а затем нижний, то ничего странного не произойдет. Но что будет, если игрок сначала разобъет нижний ящик? Верхний упадет? Как бы не так!
Верхний останется как ни в чем не бывало висеть в воздухе без опоры. Так не бывает. Поэтому необходимо сделать так, чтобы при разрушении нижнего ящика, верхний также бы разрушался. Вот как можно этого добиться.
Дадим каждому ящику (объекту func_breakable) имя. Верхний назовем crate1, а нижний — crate2. Выставим необходимые свойства (материал, прочность и т.д.). Теперь важный момент. В параметр "Target on Break" нижнего ящика запишем имя верхнего: crate1.
Теперь если мы разобъем нижний ящик, он активирует верхний, и тот также разобъется, но уже без помощи игрока. Ну, а если мы разобъем сначала верхний ящик, то нижний, как и положено, останется цел. Таким образом, мы придадим нашей карте больше реалистичности. Главное, чтобы это было кому-нибудь нужно :)

5. Ящики вместо лестниц

В некоторых местах на карте ящики могут заменить лестницу. Например, на CS_ITALY по ящикам можно забраться в комнатку около респауна контров или пробраться в дом около респауна террористов.
Ящики могут заменить лестницу
Единственное, что нужно учитывать при создании таких ящиков — их размер. Стандартными размерами ящиков являются:
48х48х48
64х64х64
80х80х80
96х96х96
112х112х112
128х128х128
Однако, стандартные, не означает, что ящики должны быть именно таких размеров. К тому же на ящики и вообще любые другие препятствия выше 62 юнитов игрок забраться не может. Так что на стандартный 64х64х64 ящик игроку без помощи напарников не залесть.
Чтобы игрок мог самостоятельно залесть на ящик нужно уменьшить его размеры, скажем до 60х60х60 юнитов или до 56х56х56 юнитов (56 юнитов удобны тем, что в редакторе не нужно будет делать слишком маленький размер клетки, хватит и 8 юнитов).

6. Передвигаемые ящики

Здесь ничего сложного нет, превращаем ящик в func_pushable и выставляем требуемые свойства. Единственное, что необходимо помнить, если для данного объекта поставть флаг breakable, то ящик можно будет разбить всего 1 раз, т.к. после своего первого разбиения, он исчезнет до конца игры, пока карта не будет перезапущена. Так происходит, например, с табуреткой на карте CS_ESTATE, которая блокирует дверь. Если табуретку разбить, она больше не появится.
Этот "подарочек" достался CS от своего родителя — Half-Life. В Half-Life нет такого понятия как раунды, и поэтому объекты в HL исчезали навсегда. В CS, к сожалению, происходит точно также, поэтому постоянно приходится быть начеку.
Что еще можно добавить к сказанному, наверное, нужно посоветовать не превращать свою карту в склад. Да, ящики в некоторых случаях незаменимы, и ящик с красивой текстурой может прекрасно вписаться в дизайн карты и улучшить ее внешний вид, но все же старайтесь не перебарщивать, придумывайте побольше естественных укрытий или, на худой конец, заменяйте ящики мусорными баками, бочками, изношенными покрышками, какими-нибудь приборами, трансформаторами — в общем придумывайте!
Вот, пожалуй, это основная информация о ящиках, которую должен знать каждый маппер.