Ваша первая Entity
Нашим последним примером было создание Entity-модели . В этой же статье мы будем использовать архитектуру мира (или брашей), для представления нашей entity, как она сталкивается и перемещается по миру. Также рассмотрим функцию "touch", доступную для всех entity. Это позволит нам создать объект, двигающийся при прикосновении игрока.
Создаем .cpp файл для новой entity
- Создадим файл, называемый
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 ); };
Мы наследуем нашу entity от класса 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() в которой разместим наш код движения. Затем мы должны сообщить entity использовать SOLID_VPHYSICS
, создающую коллизию для объекта. Установим использование MOVETYPE_PUSH
что означает позволить двигать энтити втречающиеся на нашем пути, вместо обычной блокировки.
В этом примере мы используем SetModel()
с именем модели из редактора. В связи с этим entity использует ту брашевую модель, которая определена на карте.
bool CMyBrushEntity::CreateVPhysics( void ) { // Для столкновения с объектами физики VPhysicsInitShadow( false, false ); return true; }
Напоследок, вызываем CreateVPhysics()
для установки отражения коллизии. Это то, что создает отталкивание с физическими объектами мира. Без этого браш бужет пролетать сквозь эти объекты.
Создаем BrushTouch() функцию
Entity должна оповестить нас когда она была дотронута через функцию 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
.)