Разработка 3D игр на Urho3D: от установки до публикации проекта

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Начинающие и опытные разработчики игр, интересующиеся созданием 3D проектов на Urho3D.
  • Студенты или профессионалы, изучающие программирование на C++ и желающие расширить свои навыки в геймдеве.
  • Игровые энтузиасты, ищущие доступные инструменты и ресурсы для самостоятельного создания игр.

    Разработка 3D игр давно перестала быть привилегией избранных студий с многомиллионными бюджетами. Появление мощных и доступных игровых движков открыло двери в мир геймдева практически каждому энтузиасту. Среди множества инструментов особое место занимает Urho3D — открытый, кроссплатформенный движок, объединяющий производительность C++ с простотой использования. Это идеальный баланс между гибкостью низкоуровневых инструментов и удобством высокоуровневых функций, который позволяет воплотить практически любую игровую идею без лицензионных ограничений. Давайте разберемся, как с нуля создать полноценную 3D игру на этом многообещающем движке. 🎮

Интересуетесь разработкой игр, но не знаете, с чего начать? Курс Java-разработки от Skypro станет твердым фундаментом для освоения игровых движков. Java — универсальный язык, принципы которого применимы во многих областях программирования, включая игровую индустрию. Освоив Java, вы легче перейдете к C++ для Urho3D, так как поймете ключевые концепции ООП, управления памятью и структур данных. Создайте свою первую игру, начав с фундаментальных знаний!

Основы Urho3D: установка и настройка среды разработки

Urho3D — это легковесный, но мощный графический движок с открытым исходным кодом, идеально подходящий как для новичков, так и для опытных разработчиков. Начнем с правильной настройки среды разработки — это фундамент успешного проекта. 🛠️

Для установки Urho3D существует несколько методов, но я рекомендую сборку из исходного кода для максимальной гибкости настройки. Потребуется следующее:

  • Git для клонирования репозитория
  • CMake версии 3.10 или выше
  • Компилятор C++ (Visual Studio, GCC или Clang)
  • DirectX или OpenGL SDK (в зависимости от целевой платформы)

Выполните следующие команды для получения и сборки движка:

  1. Клонируйте репозиторий: git clone https://github.com/urho3d/Urho3D.git
  2. Создайте директорию для сборки: mkdir build && cd build
  3. Сконфигурируйте проект: cmake ../Urho3D -DCMAKE_BUILD_TYPE=Release
  4. Скомпилируйте: cmake --build . --config=Release

После успешной компиляции важно настроить среду разработки под ваши нужды. В таблице ниже приведены рекомендуемые IDE для разных платформ и их особенности:

IDE Платформа Преимущества Интеграция с Urho3D
Visual Studio Windows Мощный отладчик, интеллисенс Высокая (полная поддержка CMake)
CLion Кроссплатформенная Умный анализ кода, поддержка CMake Очень высокая
Visual Studio Code Кроссплатформенная Легковесность, расширяемость Средняя (требует настройки)
Xcode macOS Интеграция с Apple экосистемой Средняя

Для создания нового проекта используйте скрипт cmake_generic.bat (Windows) или cmake_generic.sh (Linux/macOS), находящийся в директории Scripts. Этот скрипт автоматически создаст шаблон проекта со всеми необходимыми зависимостями.

После установки проверьте работоспособность движка, запустив демо-приложения из директории bin. Если все прошло успешно, вы готовы начать разработку собственной игры. 🚀

Михаил Дронов, ведущий инженер-программист

Когда я впервые столкнулся с Urho3D, я потратил почти неделю на правильную настройку среды. Множество зависимостей и специфические требования движка превратились в настоящий кошмар. Дело дошло до того, что я почти решил отказаться от Urho3D в пользу более популярного решения. Однако проблема оказалась в несовместимости версий компонентов.

Я обнаружил, что Urho3D крайне чувствителен к версиям CMake и компилятора. Решением стало использование точных версий, указанных в документации: CMake 3.15.7 и Visual Studio 2019. После этого сборка прошла без единой ошибки за 15 минут. Этот опыт научил меня, что при работе с Urho3D следует строго придерживаться рекомендаций по версиям инструментов — это сэкономит дни фрустрации и позволит быстрее перейти к самому интересному — разработке игры.

Пошаговый план для смены профессии

Архитектура Urho3D и создание первой 3D сцены

Urho3D построен на компонентной архитектуре, что делает его невероятно гибким инструментом для разработки. Понимание этой архитектуры — ключ к эффективному использованию движка. 🏗️

Основные элементы архитектуры Urho3D:

  • Context — центральный объект, управляющий регистрацией и доступом к подсистемам и объектам
  • Node — базовый элемент для построения сцены, может содержать другие узлы и компоненты
  • Component — функциональные блоки, добавляемые к узлам (модели, свет, физика)
  • Scene — корневой узел, содержащий все объекты игры
  • ResourceCache — подсистема для загрузки и управления ресурсами

Теперь создадим простую 3D сцену, демонстрирующую основы работы с движком:

cpp
Скопировать код
#include <Urho3D/Engine/Application.h>
#include <Urho3D/Graphics/Camera.h>
#include <Urho3D/Graphics/Light.h>
#include <Urho3D/Graphics/Model.h>
#include <Urho3D/Graphics/Octree.h>
#include <Urho3D/Graphics/Renderer.h>
#include <Urho3D/Graphics/StaticModel.h>
#include <Urho3D/Resource/ResourceCache.h>
#include <Urho3D/Scene/Scene.h>

class SimpleGame : public Urho3D::Application {
public:
SimpleGame(Urho3D::Context* context) : 
Application(context),
scene_(nullptr) 
{
}

virtual void Setup() {
engineParameters_["WindowTitle"] = "Моя первая Urho3D игра";
engineParameters_["FullScreen"] = false;
engineParameters_["WindowWidth"] = 1280;
engineParameters_["WindowHeight"] = 720;
}

virtual void Start() {
// Создаем сцену
scene_ = new Urho3D::Scene(context_);
scene_->CreateComponent<Urho3D::Octree>();

// Создаем камеру
Urho3D::Node* cameraNode = scene_->CreateChild("Camera");
cameraNode->SetPosition(Urho3D::Vector3(0.0f, 2.0f, -10.0f));
auto* camera = cameraNode->CreateComponent<Urho3D::Camera>();
camera->SetFarClip(300.0f);

// Настраиваем вывод на экран
auto* renderer = GetSubsystem<Urho3D::Renderer>();
Urho3D::SharedPtr<Urho3D::Viewport> viewport(
new Urho3D::Viewport(context_, scene_, camera));
renderer->SetViewport(0, viewport);

// Добавляем свет
Urho3D::Node* lightNode = scene_->CreateChild("DirectionalLight");
lightNode->SetDirection(Urho3D::Vector3(0.6f, -1.0f, 0.8f));
auto* light = lightNode->CreateComponent<Urho3D::Light>();
light->SetLightType(Urho3D::LIGHT_DIRECTIONAL);
light->SetCastShadows(true);
light->SetShadowBias(Urho3D::BiasParameters(0.00025f, 0.5f));
light->SetShadowCascade(Urho3D::CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));
light->SetBrightness(1.2f);

// Добавляем объект – коробку
Urho3D::Node* boxNode = scene_->CreateChild("Box");
boxNode->SetPosition(Urho3D::Vector3(0.0f, 0.0f, 0.0f));
boxNode->SetScale(2.0f);
auto* boxObject = boxNode->CreateComponent<Urho3D::StaticModel>();
boxObject->SetModel(GetSubsystem<Urho3D::ResourceCache>()->GetResource<Urho3D::Model>("Models/Box.mdl"));
}

private:
Urho3D::SharedPtr<Urho3D::Scene> scene_;
};

URHO3D_DEFINE_APPLICATION_MAIN(SimpleGame)

Этот код создает простую сцену с коробкой, камерой и направленным светом. Разберем ключевые моменты:

  1. Мы наследуем наш класс от Application, базового класса для приложений Urho3D
  2. В методе Setup() настраиваем параметры запуска
  3. В методе Start() инициализируем сцену и создаем необходимые объекты
  4. Макрос URHO3DDEFINEAPPLICATION_MAIN создает точку входа в программу

Одна из сильных сторон Urho3D — система событий, позволяющая создавать слабосвязанный код. Для обработки пользовательского ввода подпишемся на событие нажатия клавиш:

cpp
Скопировать код
virtual void Start() {
// ... предыдущий код ...

// Подписываемся на событие обновления кадра
SubscribeToEvent(Urho3D::E_UPDATE, URHO3D_HANDLER(SimpleGame, HandleUpdate));
}

void HandleUpdate(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData) {
// Получаем прошедшее время
float timeStep = eventData[Urho3D::Update::P_TIMESTEP].GetFloat();

// Получаем узел коробки и вращаем его
Urho3D::Node* boxNode = scene_->GetChild("Box");
if (boxNode)
boxNode->Rotate(Urho3D::Quaternion(10.0f * timeStep, 20.0f * timeStep, 30.0f * timeStep));

// Обработка ввода для перемещения камеры
Urho3D::Input* input = GetSubsystem<Urho3D::Input>();
Urho3D::Node* cameraNode = scene_->GetChild("Camera");

if (input->GetKeyDown(Urho3D::KEY_W))
cameraNode->Translate(Urho3D::Vector3(0.0f, 0.0f, 5.0f) * timeStep);
if (input->GetKeyDown(Urho3D::KEY_S))
cameraNode->Translate(Urho3D::Vector3(0.0f, 0.0f, -5.0f) * timeStep);
}

Работа с моделями, текстурами и материалами в Urho3D

Визуальная составляющая играет критическую роль в любой игре. Urho3D предлагает мощные инструменты для работы с графическими ресурсами, позволяя создавать впечатляющие 3D сцены. 🎨

Для использования моделей в Urho3D поддерживаются различные форматы, но рекомендуется конвертировать их в собственный формат движка .mdl с помощью утилиты AssetImporter, входящей в комплект поставки:

Bash
Скопировать код
AssetImporter model source_model.fbx Models/GameModel.mdl -t -na

Где параметры:

  • -t — генерировать касательные для нормального маппинга
  • -na — не оптимизировать анимацию (если она есть в модели)

После импорта модели, добавим её на сцену с применением материалов:

cpp
Скопировать код
// Получаем кэш ресурсов для загрузки ресурсов
ResourceCache* cache = GetSubsystem<ResourceCache>();

// Создаем узел для модели персонажа
Node* characterNode = scene_->CreateChild("Character");
characterNode->SetPosition(Vector3(0.0f, 0.0f, 5.0f));
characterNode->SetScale(0.5f);

// Добавляем компонент StaticModel
StaticModel* model = characterNode->CreateComponent<StaticModel>();
model->SetModel(cache->GetResource<Model>("Models/Character.mdl"));

// Создаем материал
SharedPtr<Material> material = MakeShared<Material>(context_);
material->SetTexture(TU_DIFFUSE, cache->GetResource<Texture2D>("Textures/CharacterDiffuse.png"));
material->SetTexture(TU_NORMAL, cache->GetResource<Texture2D>("Textures/CharacterNormal.png"));
material->SetShaderParameter("MatSpecColor", Vector4(0.5f, 0.5f, 0.5f, 16.0f));

// Применяем материал к модели
model->SetMaterial(material);

Для более сложных случаев Urho3D позволяет создавать материалы с помощью XML-файлов:

xml
Скопировать код
<?xml version="1.0"?>
<material>
<technique name="Techniques/DiffNormalSpec.xml" />
<texture unit="diffuse" name="Textures/CharacterDiffuse.png" />
<texture unit="normal" name="Textures/CharacterNormal.png" />
<texture unit="specular" name="Textures/CharacterSpecular.png" />
<parameter name="MatDiffColor" value="1 1 1 1" />
<parameter name="MatSpecColor" value="0.5 0.5 0.5 16" />
</material>

Сохраните этот файл как Materials/Character.xml и загрузите материал:

cpp
Скопировать код
// Загрузка материала из XML-файла
model->SetMaterial(cache->GetResource<Material>("Materials/Character.xml"));

Urho3D также поддерживает системы частиц, которые идеально подходят для эффектов огня, дыма, магии и прочих визуальных эффектов:

cpp
Скопировать код
// Создаем узел для системы частиц
Node* particleNode = scene_->CreateChild("FireEffect");
particleNode->SetPosition(Vector3(0.0f, 1.0f, 0.0f));

// Создаем компонент системы частиц и задаем эффект
ParticleEmitter* emitter = particleNode->CreateComponent<ParticleEmitter>();
emitter->SetEffect(cache->GetResource<ParticleEffect>("Particle/Fire.xml"));

Сравнение различных подходов к текстурированию в Urho3D:

Метод Преимущества Недостатки Применение
Программное создание материалов Динамическое изменение, гибкость Сложность управления большим количеством Процедурные материалы, динамические эффекты
XML-материалы Легкость редактирования, переиспользование Нельзя изменять в реальном времени без перезагрузки Статические объекты, стандартные материалы
Встроенные в модель материалы Простота использования Ограниченная гибкость настройки Прототипирование, простые проекты
PBR (Physically Based Rendering) Реалистичное освещение, современный подход Требует больше ресурсов, сложнее настроить Высококачественные игры, реалистичная графика

Алексей Кузнецов, технический арт-директор

Помню свой первый серьезный проект на Urho3D — мобильную игру с открытым миром и десятками уникальных персонажей. Ограничения платформы заставляли экономить каждый мегабайт текстур и каждый полигон модели.

Изначально я использовал стандартный подход: отдельные текстуры для каждого персонажа. Но когда память устройств начала трещать по швам, пришлось полностью пересмотреть конвейер ресурсов. Решением стало использование атласов текстур и модульных персонажей. Я разбил каждого персонажа на взаимозаменяемые части (голова, тело, конечности) и создал единые текстурные атласы для каждой категории.

Кульминацией стала система процедурной модификации материалов. Вместо хранения десятков вариаций текстур я применил процедурное изменение цветов и параметров поверхностей через шейдеры Urho3D. Это позволило создавать сотни визуально различных персонажей при минимальных затратах памяти. В результате размер игры уменьшился на 70%, а производительность рендеринга выросла в 2 раза. Этот опыт научил меня, что иногда архитектурное решение эффективнее, чем простая оптимизация существующего подхода.

Реализация физики и управления персонажем в Urho3D

Для создания интерактивного игрового опыта необходимо реализовать физику объектов и управление персонажем. Urho3D использует физический движок Bullet, обеспечивающий реалистичную симуляцию. 🏃‍♂️

Начнем с добавления физических компонентов в нашу сцену:

cpp
Скопировать код
// Создаем физический мир
scene_->CreateComponent<PhysicsWorld>();

// Создаем землю
Node* groundNode = scene_->CreateChild("Ground");
groundNode->SetScale(Vector3(50.0f, 1.0f, 50.0f));
groundNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));

// Визуальная модель земли
StaticModel* groundModel = groundNode->CreateComponent<StaticModel>();
groundModel->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
groundModel->SetMaterial(cache->GetResource<Material>("Materials/Ground.xml"));

// Физическая модель земли (статическое твердое тело)
RigidBody* groundBody = groundNode->CreateComponent<RigidBody>();
groundBody->SetFriction(1.0f);
CollisionShape* groundShape = groundNode->CreateComponent<CollisionShape>();
groundShape->SetBox(Vector3::ONE);

Теперь создадим управляемого персонажа с использованием компонента Character Controller:

cpp
Скопировать код
// Создаем узел персонажа
Node* playerNode = scene_->CreateChild("Player");
playerNode->SetPosition(Vector3(0.0f, 1.0f, 0.0f));

// Визуальная модель персонажа
StaticModel* playerModel = playerNode->CreateComponent<StaticModel>();
playerModel->SetModel(cache->GetResource<Model>("Models/Capsule.mdl"));
playerModel->SetMaterial(cache->GetResource<Material>("Materials/Player.xml"));

// Физическая модель персонажа
RigidBody* playerBody = playerNode->CreateComponent<RigidBody>();
playerBody->SetMass(1.0f);
playerBody->SetAngularFactor(Vector3::ZERO); // Запрещаем вращение
playerBody->SetCollisionLayer(1);

CollisionShape* playerShape = playerNode->CreateComponent<CollisionShape>();
playerShape->SetCapsule(0.7f, 1.8f, Vector3(0.0f, 0.9f, 0.0f));

// Создаем управляющий компонент
playerNode->CreateComponent<KinematicCharacterController>();

Реализуем компонент управления персонажем, унаследовав его от LogicComponent:

cpp
Скопировать код
class PlayerController : public LogicComponent {
URHO3D_OBJECT(PlayerController, LogicComponent);

public:
PlayerController(Context* context) : LogicComponent(context),
moveSpeed_(5.0f),
rotationSpeed_(100.0f),
onGround_(false),
jumpForce_(10.0f)
{
// Только на клиенте и только в режиме обновления сцены
SetUpdateEventMask(USE_UPDATE);
}

static void RegisterObject(Context* context) {
context->RegisterFactory<PlayerController>();
}

virtual void Update(float timeStep) {
Input* input = GetSubsystem<Input>();

// Получаем контроллер и тело
auto* body = node_->GetComponent<RigidBody>();
auto* controller = node_->GetComponent<KinematicCharacterController>();

if (!body || !controller)
return;

// Проверяем, находится ли персонаж на земле
onGround_ = controller->OnGround();

// Направление движения
Vector3 moveDir = Vector3::ZERO;

// Обрабатываем ввод
if (input->GetKeyDown(KEY_W))
moveDir += Vector3::FORWARD;
if (input->GetKeyDown(KEY_S))
moveDir += Vector3::BACK;
if (input->GetKeyDown(KEY_A))
moveDir += Vector3::LEFT;
if (input->GetKeyDown(KEY_D))
moveDir += Vector3::RIGHT;

// Прыжок
if (input->GetKeyDown(KEY_SPACE) && onGround_) {
body->ApplyImpulse(Vector3::UP * jumpForce_);
}

// Нормализуем и применяем скорость
if (moveDir.LengthSquared() > 0.0f)
moveDir.Normalize();

// Поворачиваем персонажа в направлении движения
if (moveDir != Vector3::ZERO) {
Quaternion targetRot = Quaternion(Vector3::FORWARD, moveDir);
node_->SetRotation(node_->GetRotation().Slerp(targetRot, timeStep * rotationSpeed_));
}

// Применяем скорость через контроллер персонажа
controller->SetWalkDirection(moveDir * moveSpeed_ * timeStep);
}

private:
float moveSpeed_;
float rotationSpeed_;
float jumpForce_;
bool onGround_;
};

Регистрируем и добавляем компонент к персонажу:

cpp
Скопировать код
// В функции Start() регистрируем компонент
PlayerController::RegisterObject(context_);

// Добавляем контроллер к узлу персонажа
playerNode->CreateComponent<PlayerController>();

Для создания более сложной физической среды, добавим несколько динамических объектов:

cpp
Скопировать код
// Функция для создания физического ящика
Node* CreateBox(Vector3 position, Vector3 size, float mass) {
Node* boxNode = scene_->CreateChild("PhysicsBox");
boxNode->SetPosition(position);

// Визуальная модель
StaticModel* boxModel = boxNode->CreateComponent<StaticModel>();
boxModel->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
boxModel->SetMaterial(cache->GetResource<Material>("Materials/Box.xml"));
boxNode->SetScale(size);

// Физическая модель
RigidBody* boxBody = boxNode->CreateComponent<RigidBody>();
boxBody->SetMass(mass);
boxBody->SetFriction(0.75f);
boxBody->SetRestitution(0.1f); // Упругость

CollisionShape* boxShape = boxNode->CreateComponent<CollisionShape>();
boxShape->SetBox(Vector3::ONE);

return boxNode;
}

// Создаем несколько ящиков
for (int i = 0; i < 10; ++i) {
Vector3 position(Random(10.0f) – 5.0f, 0.5f + i * 1.0f, Random(10.0f) – 5.0f);
Vector3 size(Random(1.0f) + 0.5f, Random(1.0f) + 0.5f, Random(1.0f) + 0.5f);
CreateBox(position, size, 1.0f);
}

Публикация и оптимизация вашей Urho3D игры

После разработки базовой функциональности игры, настало время подготовить её к публикации и оптимизировать производительность. Этот этап критически важен для обеспечения плавного игрового процесса на целевых платформах. 🚀

Начнем с оптимизации ресурсов, которая значительно влияет на общую производительность:

  1. Оптимизация моделей — уменьшите количество полигонов для дальних объектов и создайте LOD-версии (Level of Detail) для ключевых моделей
  2. Компрессия текстур — используйте форматы DXT/ETC/ASTC в зависимости от платформы
  3. Атласы текстур — объединяйте несколько мелких текстур в одну большую для уменьшения переключений состояния GPU
  4. Оптимизация шейдеров — создайте облегченные версии шейдеров для мобильных платформ

Для компрессии текстур в Urho3D используйте утилиту TextureCompressor:

Bash
Скопировать код
TextureCompressor Textures/Original/diffuse.png Textures/diffuse.dds -t dxt5

Основные техники оптимизации производительности в Urho3D:

  • Окклюзионные запросы — используйте OcclusionBuffer для исключения невидимых объектов из рендеринга
  • Инстансинг — применяйте для рендеринга множества одинаковых объектов (деревья, трава)
  • Оптимизация физики — используйте упрощенные коллайдеры и отключайте физику для удаленных объектов
  • Пулинг объектов — переиспользуйте объекты вместо постоянного создания/удаления

Пример настройки инстансинга для рендеринга растительности:

cpp
Скопировать код
// Создаем узел для размещения растительности
Node* vegetationNode = scene_->CreateChild("Vegetation");

// Загружаем модель травы
Model* grassModel = cache->GetResource<Model>("Models/Grass.mdl");
Material* grassMaterial = cache->GetResource<Material>("Materials/Grass.xml");

// Создаем компонент StaticModelGroup для инстансинга
StaticModelGroup* grassGroup = vegetationNode->CreateComponent<StaticModelGroup>();
grassGroup->SetModel(grassModel);
grassGroup->SetMaterial(grassMaterial);

// Добавляем экземпляры травы
for (int i = 0; i < 1000; ++i) {
Vector3 position(Random(100.0f) – 50.0f, 0.0f, Random(100.0f) – 50.0f);
float rotation = Random(360.0f);
float scale = 0.5f + Random(1.0f) * 0.5f;

// Добавляем экземпляр с заданной трансформацией
grassGroup->AddInstance(Matrix3x4(position, Quaternion(0.0f, rotation, 0.0f), scale));
}

Процесс сборки и публикации игры для различных платформ:

  1. Используйте CMake для генерации проектов под конкретные платформы
  2. Для Android/iOS необходимо настроить специфические для платформ манифесты и настройки
  3. На этапе сборки включите оптимизации компилятора для релизных версий
  4. Упакуйте ресурсы в PAK-файлы для более быстрой загрузки и защиты контента

Пример сборки релизной версии для Windows:

Bash
Скопировать код
# Создание директории для сборки
mkdir build-release && cd build-release

# Генерация проекта Visual Studio с оптимизациями
cmake ../Urho3D -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release -DURHO3D_PACKAGING=1

# Сборка
cmake --build . --config Release

# Упаковка ресурсов в PAK-файл
PackageTool ../bin/Data MyGameResources.pak

Финальные шаги перед публикацией:

  • Проведите тестирование на целевых устройствах с различными характеристиками
  • Реализуйте систему телеметрии для отслеживания производительности
  • Добавьте настройки качества графики для адаптации к возможностям устройства
  • Внедрите систему профилирования для выявления узких мест (Urho3D имеет встроенный профайлер)

Для адаптивной настройки качества графики используйте следующий код:

cpp
Скопировать код
void SetupGraphicsQuality(int qualityLevel) {
auto* renderer = GetSubsystem<Renderer>();
auto* graphics = GetSubsystem<Graphics>();

switch (qualityLevel) {
case 0: // Низкое качество
renderer->SetTextureQuality(QUALITY_LOW);
renderer->SetMaterialQuality(QUALITY_LOW);
renderer->SetDrawShadows(false);
renderer->SetSpecularLighting(false);
graphics->SetTextureFilterMode(FILTER_BILINEAR);
break;

case 1: // Среднее качество
renderer->SetTextureQuality(QUALITY_MEDIUM);
renderer->SetMaterialQuality(QUALITY_MEDIUM);
renderer->SetDrawShadows(true);
renderer->SetShadowQuality(SHADOWQUALITY_PCF_16BIT);
renderer->SetSpecularLighting(true);
graphics->SetTextureFilterMode(FILTER_TRILINEAR);
break;

case 2: // Высокое качество
renderer->SetTextureQuality(QUALITY_HIGH);
renderer->SetMaterialQuality(QUALITY_HIGH);
renderer->SetDrawShadows(true);
renderer->SetShadowQuality(SHADOWQUALITY_PCF_24BIT);
renderer->SetSpecularLighting(true);
graphics->SetTextureFilterMode(FILTER_ANISOTROPIC);
graphics->SetTextureAnisotropy(4);
break;
}
}

Создание собственной 3D игры на Urho3D — мощный шаг в мир игровой разработки без ограничений коммерческих движков. Освоив основы установки, настройки, архитектуры движка, создания графических ресурсов и реализации интерактивности, вы получили цельное представление о процессе разработки. Следующим шагом будет развитие вашей базовой игры, добавление более сложных механик, расширение игрового мира и проработка деталей. Помните — даже самые сложные игры начинаются с простого проекта, подобного тому, что мы создали в этом руководстве. Превратите полученные знания в фундамент для своих уникальных игровых вселенных! 🎮✨

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Какой инструмент необходим для сборки Urho3D на Windows?
1 / 5

Загрузка...