Ваша первая Entity

From Valve Developer Community
< Ru
Jump to: navigation, search
English (en)Русский (ru)Translate (Translate)


Нашим последним примером было создание Entity-модели(en). В этой же статье мы будем использовать архитектуру мира (или брашей), для представления нашей entity, как она сталкивается и перемещается по миру. Также рассмотрим функцию "touch", доступную для всех entity. Это позволит нам создать объект, двигающийся при прикосновении игрока.

Создаем .cpp файл для новой entity

Добавляем исходный файл в проект server.dll по правому щелчку.

  • Создадим файл, называемый sdk_brushentity.cpp.
  • Скопируем этот код(en) и вставим его в наш новый файл.
  • В последнею очередь добавляем этот файл в ваш проект 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-функию которую потом будем использовать. Смотрите документ о таблице описания данных(en) для дополнительной информации.

Создаем 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 формата(en) для дополнительной информации о FGD файлах.

Запись FGD позволяет вам привезать энтити к браше.

@SolidClass base(Targetname) = my_brush_entity : "Tutorial brush entity."
[
	
]

Если ваш .FGD не пустой, убедитесь что добавили строку @include "base.fgd", которая даст вам некоторые нужные функции Хаммера. (При полном преобразование. Мод основанный на существующем содержимом, включайте соответствующие FGD файлы; на пример для HL2(en) мода, включите halflife2.fgd вместо base.fgd.)