Ru/Authoring a Brush Entity
Template:Otherlang2 Наш последний пример был создание энтити модели. Здесь мы будем использовать архитектуру мира (или брашей) для представления нашей энтити, как она сталкивается и перемещается по миру. Также рассмотрим функцию touch, доступную для всех энтитей. Это позволит нам создать энтить которая будет двигаться когда мы будет дотрагиваться до нее.
Создаем CPP файл для новой энтити
- Создаем файл называемый
sdk_brushentity.cpp
. Этот файл должен быть внутри пакпки dlls которая находить в папке с вашим исходным кодом. Например, если вы установили код вC:\MyMod\src
, тогда вы должны создать файл называемыйC:\MyMod\src\dlls\sdk_brushentity.cpp
. - Далее копируем этот код и вставляем его в новый файл.
- В последнею очередь добавляем этот файл в ваш проект server.dll. Если вы открыли
game_sdk.sln
solution, тогда вы можете щелкнуть правой кнопкой на проекте hl в окне Solution Explorer и выбрать Add, затем Add Existing Item.
Рассмотрение кода
Создание определения класса
class CMyBrushEntity : public CBaseToggle { public: DECLARE_CLASS( CMyBrushEntity, CBaseToggle ); DECLARE_DATADESC(); void Spawn( void ); bool CreateVPhysics( void ); void BrushTouch( CBaseEntity *pOther ); };
Мы наследуем нашу энтить от класса CBaseToggle. Этот класс предоставляет некоторые базовые функции для помощи в движении брашевой модели по миру.
Определяем описание данных
LINK_ENTITY_TO_CLASS( my_brush_entity, CMyBrushEntity ); // Начинаем описание наших данных для класса BEGIN_DATADESC( CMyBrushEntity ) // Описываем функцию которая будет touch функцией DEFINE_ENTITYFUNC( BrushTouch ), END_DATADESC()
Мы объявляем touch-функию которую потом будем использовать. Смотрите документ о таблице описания данных для дополнительной информации.
Создаем Spawn() функцию
void CMyBrushEntity::Spawn( void ) { // Мы не можем перехватывать соприкасания из других энтитей SetTouch( &CMyBrushEntity::BrushTouch ); // Мы должны сталкиваться с физикой SetSolid( SOLID_VPHYSICS ); // Мы должны отталкать вещи с нашего пути SetMoveType( MOVETYPE_PUSH ); // Используем нашу модель brush-и SetModel( STRING( GetModelName() ) ); // Создаем наше скорлупу физики CreateVPhysics(); }
Первым делом в этом блоке мы установим touch-функцию как указвающую на BrushTouch() в которой разместим наш код движения. Затем мы должны сообщить энтити использовать SOLID_VPHYSICS
таким образом для столкновения используется границы собственного бокса. Установим использование MOVETYPE_PUSH
что означает позволить двигать энтити втречающиеся на нашем пути, вместо обычной блокировки.
В этом примере мы используем SetModel()
с именем модели из редактора. В связи с этим энтить использует ту брашевую модель, которая определена на карте.
bool CMyBrushEntity::CreateVPhysics( void ) { // Для столкновения с объектами физики VPhysicsInitShadow( false, false ); return true; }
Напоследок, вызываем CreateVPhysics()
для установки отражения коллизий. Это то что создает отталкивание с физическими объектами мира. Без этого браш бужет пролетать сквозь эти объекты.
Создаем BrushTouch() функцию
Энтить должна оповестить нас когда она была дотронута через функцию BrushTouch()
. Затем мы принимаем это уведомление, мы должны сообщить энтити двигаться в сторону от энтити которая дотронулась до нее. Для этого, мы нуждаемся в информации о событиях связанных с дотрагиванием. Эта информация предоставляется структурой trace_t, возвращаемая функцией GetTouchTrace()
. Она возвращает текущее трассирование коллизии вызвавшее сообщение.
void CMyBrushEntity::BrushTouch( CBaseEntity *pOther ) { // Получаем информацию о коллизии const trace_t &tr = GetTouchTrace(); // Мы должны переместить прочь от удара вдоль нашей поверхности Vector vecPushDir = tr.plane.normal; vecPushDir.Negate(); vecPushDir.z = 0.0f; // Перемещаем медленно в этом направление LinearMove( GetAbsOrigin() + ( vecPushDir * 64.0f ), 32.0f ); }
Первым делом мы извлекаем нормаль поверхности которая была дотронута. Для этого, нужна одна из плоскостей браш-энтити. Мы вычитаем это значение для указания относительного направления столкновения, затем убираем Z компоненту направления для сохранения паралельности к полу.
Напоследок, используем функцию LinearMove()
заставляющая двигаться браш в направлении с заданной скоростью. Функция LinearMove()
имплементируется классом CBaseToggle
и заботится о рутинной работе связанной с тем как обеспечивается движение брашевой модели.
Создаем запись в FGD файле
Для использования энтити в Хаммере, мы должны создать запись в FGD файле. Хаммер будет использовать эти данные для того чтобы понять различные ключевые значения и функции которые предоставляет энтитя. Смотрите документ FGD формата для дополнительной информации о FGD файлах.
Запись FGD позволяет вам привезать энтити к браше.
@SolidClass base(Targetname) = my_brush_entity : "Tutorial brush entity." [ ]
Если ваш .FGD не пустой, убедитесь что добавили строку @include "base.fgd", которая даст вам некоторые нужные функции Хаммера. (При полном преобразование. Мод основанный на существующем содержимом, включайте соответствующие FGD файлы; на пример для HL2 мода, включите halflife2.fgd
вместо base.fgd
.)