[C++, Разработка игр] Source Modding — Часть 2 — Всё есть сущность

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
15-Июл-2020 19:32

Source Engine никогда не постареет. Во всяком случае умирать он еще не собирается.
В предыдущей части урока мы научились базовой работе с VPC и печати сообщений в консоль разработчика.
В этой части урока мы разберем систему энтити, научимся создавать классы и создадим нашу первую логическую сущность.

Опять термины
Сущность или Энтити(entity) — основной объект на уровне.
Система I/O — система, предназначенная для "общения" сущностей друг с другом.
Инпут(input) — команда, меняющая поведение сущности. Бывает вызвана игроком через консоль или аутпутом.
Аутпут(output) — событие, вызываемое при изменении состояния сущности.
А вообще, как это работает?
Любой уровень в Source — набор сущностей.
На каждом уровне присутствует как минимум одна сущность, называемая worldspawn. Эта сущность по факту — весь "твердый" мир, а именно:
  • Примитивы a.k.a. браши — кубы, шары, арки, etc.
  • Так называемые displacements (диспы, диспенсеры) — примитивы на стероидах, позволяющие создавать более детализированные ландшафты или (Новые карты в CS:GO используют это!) здания. Не поддаются оптимизации, а поэтому желательно прикрывать их "снизу" примитивами.
  • Статичные модели (prop_static). В отличие от тех же prop_dynamic, сущностями как таковыми не являются.

Остальные же сущности (включая игроков!) имеют свои собственные свойства и поведение.
Все сущности можно разделить вот так:

  • Точечные — это такие сущности, которые расположены в мире в определенной точке.
  • Брашевые — это такие сущности, которые состоят из примитивов.
    ВАЖНО/Hammer: Не превращайте диспы в брашевые сущности!!!

Логическая энтити
Логические сущности — самые простые из всех, так как не имеют визуального компонента и коллизии. Самые простые и самые полезные!
Например, сущность logic_auto через несколько аутпутов обрабатывает события запуска карты в различных режимах.
logic_5 — код
Давайте создадим простую сущность, которая при каждом пятом вызове инпута будет печатать цветное сообщение в консоль.
  • В проекте серверной части игры создайте файл с названием logic_5.cpp.
    То есть, файл будет лежать по пути: src/game/server/logic_5.cpp.
  • Включите необходимые заголовки в наш файл:
    // cbase.h - прекомпилированный заголовок.
    // Он включает в себя всё необходимое для базового программирования под сурс.
    #include "cbase.h"
    // memdbgon.h - заголовок с переопределениями операторов new и delete
    // memdbgon must be the last include file in a .cpp file!!!
    #include "tier0/memdbgon.h"

  • Создайте класс CLogicFive наследующий CLogicEntity:
    class CLogicFive : public CLogicEntity {
        DECLARE_CLASS( CLogicFive, CLogicEntity );
    public:
        // ...
    private:
        // ...
    };

    Погодите-ка! Что за DECLARE_CLASS()? Это специальный макрос, предназначенный для облегчения работы при множественном наследовании. Он определяет два типа — ThisClass для текущего класса и BaseClass для базового класса (этот тип мы кстати видели в предыдущей части урока...).
  • Добавьте определения под public:
    public:
        DECLARE_DATADESC();
        void Input_Tick( inputdata_t &id );

    Ну и что есть что?
    • DECLARE_DATADESC() это макрос, объявляющий таблицу метаданных класса для движка.
    • void Input_Tick( inputdata_t &id ) это функция, которая будет являть собой инпут tick.

  • Добавьте счетчик тиков под private:
    private:
        int m_iTicks = 0;

  • Теперь нам необходимо как бы "прибить гвоздями" наш класс к имени сущности logic_5.
    И в этом нам поможет (еще один!) макрос — LINK_ENTITY_TO_CLASS()!
    Добавляем его сразу после объявления класса:
    // ...
        int m_iTicks = 0;
    };
    LINK_ENTITY_TO_CLASS( logic_5, CLogicFive );

  • Теперь нам необходимо определить таблицу метаданных, объявленную в шаге 4:
    BEGIN_DATADESC( CLogicFive )
        DEFINE_FIELD( m_iTicks, FIELD_INTEGER ), // наш счетчик тиков
        DEFINE_INPUTFUNC( FIELD_VOID, "tick", Input_Tick ), // наш инпут
    END_DATADESC();

    • BEGIN_DATADESC() — макрос, раскрывающийся в начало таблицы метаданных для класса.
    • DEFINE_FIELD() — макрос, создающий в таблице поле. Любое поле, добавленное этим макросом в таблицу будет иметь своё место в файлах сохранения!
    • DEFINE_INPUTFUNC() — макрос, определяющий инпут. В нашем случае он ничего не возвращает (FIELD_VOID), называется tick и ссылается на метод Input_Tick.
    • END_DATADESC() — макрос, раскрывающийся в конец таблицы метаданных.

  • Из необходимого остается только реализовать метод Input_Tick:
    // обработчик инпута tick()
    void CLogicFive::Input_Tick( inputdata_t &id )
    {
        m_iTicks++;
        if( m_iTicks % 5 == 0 )
            // если новое количество тиков делится на пять, напечатать цветное сообщение!
            ConColorMsg( Color( 255, 255, 0 ), "logic_five: Another fifth tick!\n" );
    }

  • [НЕОБЯЗАТЕЛЬНО] Добавьте наш файл в VPC скрипт:
    // src/game/server/server_episodic.vpc
    // где-то внутри $Folder "Source Files"
    $File "$SRCDIR/game/server/logic_5.cpp

    Затем, разумеется, перегенерируйте решение.

logic_5 — в игре
  • Запустите игру и любую карту (sdk_vehicles или dm_lockdown, например)
  • Создайте нашу сущность консольной командой:
    ent_create logic_5
  • Пять раз вызовите инпут tick консольной командой:
    ent_fire logic_5 tick
  • После пятого вызова в консоли должно появиться желтое (или любого другого цвета если вы его поменяли) сообщение!

Заключение
Чему мы научились?
[Я надеюсь, что] из этой части урока вы узнали:
  • Что такое сущности и каких видов они бывают
  • Что такое система ввода-вывода у сущностей
  • Как создавать свои логические сущности

Что будет дальше?
В третьей части я расскажу о основах редактора Valve Hammer Editor и структуре FGD файлов.
Это будет необходимо, так как частью позже я буду дополнять этот урок, добавляя нашей сущности вместо консольного сообщения аутпут.
Полезные ссылки

===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_c++, #_razrabotka_igr (Разработка игр), #_tutorial, #_source_engine, #_source_sdk, #_c++, #_gamedev, #_c++, #_razrabotka_igr (
Разработка игр
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 20:33
Часовой пояс: UTC + 5