Предыдущий пример касался задание модели для энтити. Сдесь мы будем использовать архитектуру мира (или
брашей) для представления нашей энтити, как она коллизится и двигается по миру. Также рассмотрим функцию
touch, доступную для всех энтитей. Это позволит нам создать энтить которая будет двигаться когда мы будет дотрагиваться до нее.
1) Создаем файл используя код из ..\dlls\sdk\sdk_brushentity.cpp и добавляем его к проекту server
2) Добавляем определение класса
class CMyBrushEntity : public CBaseToggle
{
public:
DECLARE_CLASS( CMyBrushEntity, CBaseToggle );
DECLARE_DATADESC();
void Spawn( void );
bool CreateVPhysics( void );
void BrushTouch( CBaseEntity *pOther );
};
Мы наследуем нашу энтить от класса
CBaseToggle. Этот класс предоставляет некоторые базовые функции для помощи в движении брашевой модели по миру.
3)
Определяем описание данных для данного класса
LINK_ENTITY_TO_CLASS( my_brush_entity, CMyBrushEntity );
// Start of our data description for the class
BEGIN_DATADESC( CMyBrushEntity )
// Declare this function as being a touch function
DEFINE_ENTITYFUNC( BrushTouch ),
END_DATADESC()
Мы объявдяем touch-функию которую потом будем использовать. Для более детальной информации смотрите о
таблице описаний данных.
4) Создаем Spawn() функцию
void CMyBrushEntity::Spawn( void )
{
// 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();
}
Первым делом в этом блоке мы установим touch-функцию как указвающую на
BrushTouch() в которой разместим наш код движения. Затем мы должны сообщить энтити использовать
SOLID_VPHYSICS таким образом для коллижина используется границы собственного бокса. Установим использование
MOVETYPE_PUSH что означает позволить двигать энтити втречающиеся на нашем пути, вместо обычной блокировки.
В этом примере мы используем
SetModel() с именем модели из редактора. В связи с этим энтить использует ту брашевую модель, которая определена на карте.
bool CMyBrushEntity::CreateVPhysics( void )
{
// For collisions with physics objects
VPhysicsInitShadow( false, false );
return true;
}
Напоследок, вызываем
CreateVPhysics() для
установки отражения коллизий. Это то что создает отталкивание с
физическими объектами мира. Без этого браш бужет пролетать сквозь эти
объекты.
5)
Создаем BrushTouch() функцию
Энтить должна оповестить нас когда она была дотронута через функцию
BrushTouch().
Затем мы принимаем это уведомление, мы должны сообщить энтити двигаться
в сторону от энтити котораядотронулась до нее. Для этого, мы нуждаемся
в информации о событиях связанных с дотрагиванием. Эта информация
предоставляется структурой
trace_t, возвращаемая функцией
GetTouchTrace(). Она возвращает текущее трассирование коллизии вызвавшее сообщение.
void CMyBrushEntity::BrushTouch( CBaseEntity *pOther )
{
// 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 );
}
Первым делом мы извлекаем нормаль поверхности которая была дотронута.
Для этого, нужна одна из плоскостей браш-энтити. Мы вычитаем это
значение для указания относительного направления столкновения, затем
убираем Z компоненту направления для сохранения паралельности к полу.
Напоследок, используем функцию
LinearMove() заставляющая двигаться браш в направлении с заданной скоростью. Функция
LinearMove() имплементируется классом
CBaseToggle и заботится о рутинной работе связанной с тем как обеспечивается движение брашевой модели.
6)
Компиляция и запуск
Загрузите карту
sdk_entity_brush. Подбежите к
браш-энтите что перед вами и дотроньтесь до него. Браш будет двигаться
короткое время и остановиться. Дотронтесь к ней опять, движение
повториться.
Попробуйте изменить дальность его движения или скорость. Можно добавить функцию
think для реализации более сложного поведения энтити.