Создание Brush Entity
Предыдущий пример касался задание модели для энтити. Сдесь мы будем использовать архитектуру мира (или брашей) для представления нашей энтити, как она коллизится и двигается по миру. Также рассмотрим функцию touch, доступную для всех энтитей. Это позволит нам создать энтить которая будет двигаться когда мы будет дотрагиваться до нее.
В этом примере мы используем SetModel () с именем модели из редактора. В связи с этим энтить использует ту брашевую модель, которая определена на карте.
Энтить должна оповестить нас когда она была дотронута через функцию BrushTouch (). Затем мы принимаем это уведомление, мы должны сообщить энтити двигаться в сторону от энтити котораядотронулась до нее. Для этого, мы нуждаемся в информации о событиях связанных с дотрагиванием. Эта информация предоставляется структурой trace_t, возвращаемая функцией GetTouchTrace (). Она возвращает текущее трассирование коллизии вызвавшее сообщение.
Напоследок, используем функцию LinearMove () заставляющая двигаться браш в направлении с заданной скоростью. Функция LinearMove () имплементируется классом CBaseToggle и заботится о рутинной работе связанной с тем как обеспечивается движение брашевой модели.
Загрузите картуsdk_entity_brush. Подбежите к браш-энтите что перед вами и дотроньтесь до него. Браш будет двигаться короткое время и остановиться. Дотронтесь к ней опять, движение повториться.
Попробуйте изменить дальность его движения или скорость. Можно добавить функцию think для реализации более сложного поведения энтити.
1) Создаем файл используя код из .\\dlls\\sdk\\sdk_brushentity.cpp и добавляем его к проекту server
2) Добавляем определение класса
class CMyBrushEntity: public CBaseToggleМы наследуем нашу энтить от класса CBaseToggle. Этот класс предоставляет некоторые базовые функции для помощи в движении брашевой модели по миру.
{
public:
DECLARE_CLASS (CMyBrushEntity, CBaseToggle);
DECLARE_DATADESC ();
void Spawn (void);
bool CreateVPhysics (void);
void BrushTouch (CBaseEntity *pOther);
};
3)
Определяем описание данных для данного класса
LINK_ENTITY_TO_CLASS (my_brush_entity, CMyBrushEntity);Мы объявдяем touch-функию которую потом будем использовать. Для более детальной информации смотрите о таблице описаний данных.
// Start of our data description for the class
BEGIN_DATADESC (CMyBrushEntity)
// Declare this function as being a touch function
DEFINE_ENTITYFUNC (BrushTouch),
END_DATADESC ()
4) Создаем Spawn () функцию
void CMyBrushEntity::Spawn (void)Первым делом в этом блоке мы установим touch-функцию как указвающую на BrushTouch () в которой разместим наш код движения. Затем мы должны сообщить энтити использовать SOLID_VPHYSICS таким образом для коллижина используется границы собственного бокса. Установим использование MOVETYPE_PUSH что означает позволить двигать энтити втречающиеся на нашем пути, вместо обычной блокировки.
{
// We want to capture touches from other entities
SetTouch (BrushTouch);
// We should collide with physics
SetSolid (SOLID_VPHYSICS);
// We push things out of our way
SetMoveType (MOVETYPE_PUSH);
// Use our brushmodel
SetModel (STRING (GetModelName ()));
// Create our physics hull information
CreateVPhysics ();
}
В этом примере мы используем SetModel () с именем модели из редактора. В связи с этим энтить использует ту брашевую модель, которая определена на карте.
bool CMyBrushEntity::CreateVPhysics (void)Напоследок, вызываем CreateVPhysics () для установки отражения коллизий. Это то что создает отталкивание с физическими объектами мира. Без этого браш бужет пролетать сквозь эти объекты.
{
// For collisions with physics objects
VPhysicsInitShadow (false, false);
return true;
}
5)
Создаем BrushTouch () функцию
Энтить должна оповестить нас когда она была дотронута через функцию BrushTouch (). Затем мы принимаем это уведомление, мы должны сообщить энтити двигаться в сторону от энтити котораядотронулась до нее. Для этого, мы нуждаемся в информации о событиях связанных с дотрагиванием. Эта информация предоставляется структурой trace_t, возвращаемая функцией GetTouchTrace (). Она возвращает текущее трассирование коллизии вызвавшее сообщение.void CMyBrushEntity::BrushTouch (CBaseEntity *pOther)Первым делом мы извлекаем нормаль поверхности которая была дотронута. Для этого, нужна одна из плоскостей браш-энтити. Мы вычитаем это значение для указания относительного направления столкновения, затем убираем Z компоненту направления для сохранения паралельности к полу.
{
// Get the collision information
const trace_t &tr = GetTouchTrace ();
// We want to move away from the impact point along our surface
Vector vecPushDir = tr.plane.normal;
vecPushDir. Negate ();
vecPushDir.z = 0.0f;
// Move slowly in that direction
LinearMove (GetAbsOrigin () + (vecPushDir * 64.0f), 32.0f);
}
Напоследок, используем функцию LinearMove () заставляющая двигаться браш в направлении с заданной скоростью. Функция LinearMove () имплементируется классом CBaseToggle и заботится о рутинной работе связанной с тем как обеспечивается движение брашевой модели.
6)
Компиляция и запуск
Загрузите картуsdk_entity_brush. Подбежите к браш-энтите что перед вами и дотроньтесь до него. Браш будет двигаться короткое время и остановиться. Дотронтесь к ней опять, движение повториться.Попробуйте изменить дальность его движения или скорость. Можно добавить функцию think для реализации более сложного поведения энтити.