Туториал по Unreal Engine. Часть 7: звук

В видеоиграх под понятием «звук» подразумеваются музыка, диалоги и звуковые эффекты. В наше время игра без звука будет казаться небрежной и незавершённой.

Автор оригинала: Tommy Tran

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

В этой части туториала вы научитесь следующему:

  • Воспроизводить музыку и зацикливать её
  • Воспроизводить звуковой эффект в определённых точках анимации
  • Модулировать тон звука при каждом воспроизведении
  • Перемещать их регулировать громкость звука в зависимости его местоположения в 3D-пространстве
  • Управлять с помощью UI громкостью музыки и звуковых эффектов по отдельности

Учтите, что в этой части мы будем использовать Blueprints. Если вы ещё не читали предыдущие части, то изучите их, потому что в них рассматриваются различные аспекты Blueprints.

Также рекомендуется надеть наушники в этом туториале, потмоу что мы будем учиться пространственной локализации звука.

Примечание:эта статья является одной из восьми частей туториала, посвящённого Unreal Engine:

Приступаем к работе

Скачайтезаготовку проектаи распакуйте её. Откройте проект, перейдя в папку проекта и запустивSkywardMuffin.uproject.

Нажмите наPlay, чтобы начать игру. Цель игры — коснуться как можно больше облаков, не упав вниз. Нажмите налевую клавишу мыши, чтобы подпрыгнуть к первому облаку.

Туториал по Unreal Engine. Часть 7: звук

Игра расслабляет, не так ли? Чтобы усилить чувство расслабления, мы начнём с того, что будем воспроизводить спокойную пианинную музыку.

Воспроизведение музыки

Перейдите в Content Browser и найдите папкуAudio. Здесь находятся все звуки, которые будут использоваться в этом туториале. Их можно прослушать,наведя курсорна ихзначок, а затем нажав на появившийсязначок воспроизведения.

Туториал по Unreal Engine. Часть 7: звук

Воспроизвести музыку просто: достаточно перетащить звуковой ассет во Viewport. Однако музыка воспроизведётся толькоодин раз. Зацикленность необходимо включать в ассете вручную.Дважды щёлкнитенаS_Music, чтобы открыть его.

Туториал по Unreal Engine. Часть 7: звук

Откроется новое окно с единственной панелью Details. Перейдите в разделSound Waveи включитеLooping.

Туториал по Unreal Engine. Часть 7: звук

Затем вернитесь в основной редактор иперетащитеассетS_Musicво Viewport.

Туториал по Unreal Engine. Часть 7: звук

При этом будет создан акторAmbientSoundс источником звукаS_Music. Этот актор будет автоматически воспроизводитьS_Musicпри запуске игры.

Нажмите наPlay, чтобы прослушать музыку. Через 17 секунд (длительность музыки) она зациклится и начнётся сначала.

Туториал по Unreal Engine. Часть 7: звук

Теперь нам нужно создать звуковой эффект для шагов маффина. Для этого мы будем использоватьAnimation Notify.

Что такое Animation Notify?

Animation Notify позволяет разработчику запустить выполнение события в определённой точке анимации. Их можно использовать множеством различных способов. Например, можно создать Notify для спауна эффекта частиц.

Туториал по Unreal Engine. Часть 7: звук

В этой игре при касании маффином земли появляется кнопка перезапуска. Однако с помощью Notify можно сделать так, чтобы она появлялась вконцеанимации смерти.

Туториал по Unreal Engine. Часть 7: звук

В этом туториале мы будем использовать Animation Notify для воспроизведения звука, когда каждая из ног маффина касается земли.

Создание Animation Notify

Перейдите в папкуCharacters\Muffinи откройтеSK_Muffin_Walk. При этом откроется Animation editor.

В панели под Viewport есть область под названиемNotifies. Светло-серая область — этоNotify Track. Именно здесь мы будем создавать Notify и управлять ими.

Туториал по Unreal Engine. Часть 7: звук

Ноги маффина касаются земли вкадре 10и вкадре 22, поэтому нам нужно создать Notify для каждой из этих точек. Для создания Notifyнажмите правой клавишей мышина Notify Track и выберитеAdd Notify\Play Sound. При этом создастся Notify с названиемPlaySound.

Туториал по Unreal Engine. Часть 7: звук

Теперь нужно позиционировать Notify, чтобы он происходил вкадре 10.

Перемещение Animation Notify

Немного сложно понять, куда двигать Notify, потому что на Notify Track не показано, где находитсякадр 10. Однако можно отобразить с помощью Timeline маркер.

Во-первых, зайдите в Timeline, расположенную в нижней части панели.Перетащитекрасныйуказатель воспроизведенияи отпустите, когдаCurrent Frameбудет равен10. Сначала необходимо поставить его на паузу!

Туториал по Unreal Engine. Часть 7: звук

Теперь на Notify Track появится красная линия, сообщающая, где находится указатель воспроизведения.

Туториал по Unreal Engine. Часть 7: звук

ПеретащитеNotifyPlaySoundи отпустите его, когда он привяжется к красной линии.

Туториал по Unreal Engine. Часть 7: звук

Теперь нам нужно сказать Notify, что надо воспроизвести звук шагов.

Воспроизведение звука шагов

Нажмите левой клавишей мышинаPlaySound, чтобы выбрать его и перейдите в панель Details. В разделеAnim Notifyзадайте дляSoundзначениеS_Footstep.

Туториал по Unreal Engine. Часть 7: звук

Затем повторите процесс для следующей ноги. Сделайте следующее:

  • Создайте ещё один NotifyPlay Sound
  • Переместите Notify накадр 21
  • Выберите для Notify звукS_Footstep
Туториал по Unreal Engine. Часть 7: звук

Теперь, когда анимация ходьбы будет достигатькадра 10икадра 21, Notify будет срабатывать и запускать воспроизведение звукаS_Footstep.

ЗакройтеSK_Muffin_Walkи вернитесь в основной редактор. Нажмите наPlayи начните ходить по земле, чтобы услышать шаги.

Туториал по Unreal Engine. Часть 7: звук

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

В следующем разделе мы будем воспроизводить звуковой эффект, когда игрок касается облака. Но в этот раз мы каждый раз будем вносить вариации в звуки с помощьюSound Cue.

Что такое Sound Cue?

Sound Cue — это ассет, который позволяет манипулировать несколькими звуками и комбинировать их. Можно считать Sound Cue своим собственным звуком. Там, где можно использовать обычный звук, вы можете использовать вместо него Sound Cue.

Вот пример Sound Cue с использованиемConcatenatorдля последовательного воспроизведения трёх разных звуков:

Туториал по Unreal Engine. Часть 7: звук

Если использовать вместо него нодRandom, то вы сможете выбирать случайный звук каждый раз при воспроизведении Sound Cue.

Туториал по Unreal Engine. Часть 7: звук

В этом туториале мы создадим и будем использовать Sound Cue для изменения тона звука.

Создание Sound Cue

Сначала вернитесь в папкуAudio. Там есть звуковой эффектS_Pop, для которого мы создадим Sound Cue. Чтобы сделать это,нажмите правой клавишей мышинаS_Popи выберитеCreate Cue.

Туториал по Unreal Engine. Часть 7: звук

При этом будет создан новый ассет Sound Cue под названиемS_Pop_Cue.Дважды щёлкнитенаS_Pop_Cue, чтобы открыть его в Sound Cue editor.

Примечание:этот редактор очень похож на редактор материалов, поэтому я не буду подробно его рассматривать. Если вы незнакомы с редактором материалов, то можете узнать о нём в частиЗнакомство с движком.

В графе есть два нода:Wave Player: S_PopиOutput. Sound Cue будет воспроизводить всё, что присоединено к нодуOutput(в этом случае он воспроизводит звукS_Pop). Прослушать Sound Cue можно, перейдя в Toolbar и нажав наPlay Cue.

Туториал по Unreal Engine. Часть 7: звук

Теперь нам нужно узнать, как изменять тон звука.

Изменение тона звука

Чтобы изменить тон звука, нам нужен нодModulator. Создайте его и соедините следующим образом:

Туториал по Unreal Engine. Часть 7: звук

Теперь необходимо задать величину изменения тона. Выберите нодModulatorи перейдите в панель Details. Там есть два относящихся к тону поля:Pitch MinиPitch Max. Значения меньше 1 показывают, что тон можно уменьшить, и наоборот. Значение 1 показывает, что тон останется прежним.

В этом туториале мы будем только повышать тон. ЗадайтеPitch Minзначение1.0, аPitch Max— значение2.0.

Туториал по Unreal Engine. Часть 7: звук

Теперь при каждом воспроизведении Sound Cue звук будет иметь тон в интервале от исходного тона до удвоенного исходного тона.

Теперь нам нужно сделать так, чтобы Sound Cue воспроизводился, когда игрок касается облака.

Воспроизведение Sound Cue

Вернитесь к основному редактору и перейдите в папкуBlueprints. ОткройтеBP_Cloud, а затем функциюCloudTouched. Эта функция выполняется тогда, когда игрок касается облака, то есть это идеальное место для воспроизведения Sound Cue.

Здесь есть два нода, которые можно использовать для воспроизведения звука:

  • Play Sound 2D:воспроизводит звук без какого-либо затухания или пространственной локализации (я расскажу о них подробнее ниже). Используйте этот нод для звуков, которые не «существуют» в игровом мире, например, для музыки и звуков UI.
  • Play Sound at Location:воспроизводит звук в точке 3D-пространства. Используйте этот нод, если хотите, чтобы звук менялся в зависимости от местонахождения и направления игрока.

Поскольку облако существует в игровом мире, звук тоже должен существовать в игровом мире. Добавьте в конец цепочки нодов нодPlay Sound at Location.

Туториал по Unreal Engine. Часть 7: звук

Затем задайте дляSoundзначениеS_Pop_Cue.

Туториал по Unreal Engine. Часть 7: звук

Теперь когда игрок касается облака, будет воспроизводитьсяS_Pop_Cue.

Нажмите наCompileи вернитесь в основной редактор. Нажмите наPlayи начните играть в игру. При каждом касании облака вы должны слышать одинаковый звук с разным тоном.

Туториал по Unreal Engine. Часть 7: звук

Тон звука меняется, но непохоже. что он звучит в 3D-пространстве. Для этого необходимопозиционироватьзвук.

Что такое позиционирование?

Позиционирование — это процесс, выполняемый для создания впечатления существования звука в 3D-пространстве. Звуки, приходящие слева, будут слышны левым ухом, и наоборот.

Туториал по Unreal Engine. Часть 7: звук

Кроме того, что позиционирование усиливает ощущения погружения в игру, оно также может помочь геймплею. В соревновательных играх наподобиеOverwatchиCounter-Strike, позиционируемый звук помогает игрокам распознавать положение других игроков.

В этом туториале мы воспользуемся позиционированием для перемещения звука облака на основании его местоположения.

Создаём позиционирование

Есть два способа создания позиционирования Sound Cue:

  • Ассет Sound Attenuation:этот ассет содержит настройки, связанные с затуханием и позиционированием. Можно назначать этому ассету различные звуки, чтобы все они имели одинаковые настройки.
  • Override Attenuation:вместо ассета Sound Attenuation можно задавать настройки внутри Sound Cue. Это позволяет создавать настройки для отдельных Sound Cue.

В этом туториале мы воспользуемся вторым способом. ОткройтеS_Pop_Cueи перейдите в панель Details. Найдите разделAttenuationи включитеOverride Attenuation. При этом станет активным разделAttenuation Overrides.

Туториал по Unreal Engine. Часть 7: звук

Чтобы убедиться в том, что позиционирование включено, нажмите настрелкурядом сAttenuation Overrides. НастройкаSpatializeпоказывает, что позиционирование звука выполняется.

Туториал по Unreal Engine. Часть 7: звук

Мы закончили с настройками, поэтому можно закрытьS_Pop_Cue. Теперь нам нужно указать, где находится звук в 3D-пространстве.

Воспроизведение звука в 3D-пространстве

ОткройтеBP_Cloudи создайте нодGetActorLocation. Теперь соедините его с контактомLocationнодаPlay Sound at Location.

Туториал по Unreal Engine. Часть 7: звук

Теперь звук будет воспроизводиться в том же месте, где находится облако.

Нажмите наCompileи вернитесь в основной редактор. Нажмите наPlayи начните касаться облаков. Вы должны услышать звуки, которые будут казаться приходящими из разных мест.

Туториал по Unreal Engine. Часть 7: звук

Примечание:по умолчаниюслушателем звукаявляется камера. Это означает, что вы будете слышать звуки с точки местоположения камеры. Если вы хотите заменить слушателя другим актором, то можно использовать нодSet Audio Listener Override.

Вы наверно заметили, что из некоторых облаков идёт дождь. Но они не похожи на тучи, потому что звука дождя не слышно! Сейчас мы добавим звук дождя и используемзатухание, чтобы изменять его громкость в зависимости от расстояния.

Добавление звука дождя

Вместо использования нода для воспроизведения звука дождя можно применить компонентAudio. Одно из преимуществ использования компонента заключается в том, что он автоматически воспроизводится в точке местоположения облака.

ОткройтеBP_Cloudи перейдите в панель Components. Добавьте новый компонентAudioи назовите егоRainAudio.

Перейдите в панель Details и найдите разделSound. Измените значениеSoundнаS_Rain.

Туториал по Unreal Engine. Часть 7: звук

Звук дождя не должен воспроизводиться для обычных облаков. Это значит, что для нихRainAudioнужно деактивировать. Для этого прокрутите вниз, к разделуActivationи отключитеAuto Activate.

Туториал по Unreal Engine. Часть 7: звук

Теперь нам нужно активироватьRainAudioдля дождевых облаков. Удобно это будет делать в функцииEnableRain. Эта функция исполняется, если облако должно быть дождевым. Откройте функциюEnableRainи добавьте выделенные ноды:

Туториал по Unreal Engine. Часть 7: звук

Теперь нужно включить затухание и задать настройки затухания.

Настройка затухания

Перейдите в панель Components и выберитеRainAudio. Перейдите в панель Details и зайдите в разделAttenuation. Включите настройкуOverride Attenuation.

Настройки затухания определяют снижение громкости звука в зависимости от расстояния. В областиAttenuation Overridesесть две настройки, которыми мы можем воспользоваться:

  • Radius:максимальное расстояние, на котором может быть игрок, прежде чем громкость начнёт уменьшаться
  • Falloff Distance:расстояние, на котором может быть игрок, прежде чем звук станет неслышным. Это расстояние прибавляется к радиусу.

Посмотрите на пример:

Туториал по Unreal Engine. Часть 7: звук

Когда игрок находится в пределах внутреннего круга (задаваемого настройкойRadius), громкость равна 100%. Когда игрок двигается из внутреннего круга к краю внешнего круга (задаваемого настройкойFalloff Distance), громкость снижается до 0%.

В этом туториале мы присвоим настройкеRadiusзначение300, а настройкеFalloff Distance— значение400.

Туториал по Unreal Engine. Часть 7: звук

Это значит, что громкость звука будет равна 100%, когда игрок находится в пределах300единиц от звука. Когда расстояние будет приближаться к700(300 + 400) единицам, громкость начнём падать до 0%.

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

Плавное снижение громкости звука

Переключитесь в Event Graph и найдите событиеFadeOut. Это можно сделать, перейдя к панели My Blueprint и зайдя в разделGraphs.Дважды щёлкнитенаFadeOutв спискеEventGraph.

Добавьте в конец цепочки нодов выделенные ноды:

Туториал по Unreal Engine. Часть 7: звук

FadeOutвыполняется, когда игрок касается облака. НодTimeline(FadeTimeline) выводит значение (Alpha), которое за указанное время снижается с 1 до 0. Благодаря этому значению громкостьRainAudioбудет постепенно снижаться.

Примечание:можнодважды щёлкнутьна нодTimeline, чтобы открыть его и посмотреть, как он работает. Если вы хотите больше узнать оTimelines, то изучитеофициальную документацию.

Прежде чем услышать это в действии, необходимо изменить одну настройку вS_Rain. Когда громкость звука равна 0%, его воспроизведение останавливается. Поскольку когда звук начинается, когда мы находимся за пределами слышимости, то громкостьS_Rainбудет равна 0%. Когда мы переместимся в пределы слышимости, то ничего не услышим.

Туториал по Unreal Engine. Часть 7: звук

Это можно исправить с помощью настройкиVirtualize when Silent. Эта настройка будет всегда воспроизводить звук, вне зависимости от его громкости.

Нажмите наCompileи закройтеBP_Cloud. Перейдите в папкуAudioи откройтеS_Rain. Перейдите в разделSoundи включитеVirtualize when Silent.

Туториал по Unreal Engine. Часть 7: звук

ТеперьS_Rainбудет воспроизводиться даже тогда, когда он не слышен. ЗакройтеS_Rainи вернитесь в основной редактор. Нажмите наPlayи переместитесь в пределы слышимости дождевых облаков, чтобы услышать звук дождя.

Туториал по Unreal Engine. Часть 7: звук

В последнем разделе мы будем контролировать громкость звуков с помощьюSound ClassиSound Mix.

Sound Class и Sound Mix

Sound Class — это простой способ группировки нескольких звуков. Например, можно сгруппировать всю музыку в один класс, а звуковые эффекты — в другой.

Туториал по Unreal Engine. Часть 7: звук

Чтобы изменять свойства Sound Class (громкость, тон и т.д.) во время игрового процесса, нам нужно использовать Sound Mix. Sound — это таблица, каждая запись которой являтеся Sound Class. Каждая запись содержит настройки, которые должны быть у Sound Class.

Вот пример того, что может содержаться в Sound Mix:

Туториал по Unreal Engine. Часть 7: звук

При использовании показанного выше Sound Mix все звуки в классеMusicбудут проигрываться с половинной громкостью. У всех звуков в классеEffectsбудет удвоен тон.

Во-первых, мы создадим классы звука (Sound Class).

Создание классов звука

В этом туториале мы будем отдельно регулировать громкость музыки и эффектов. Это значит, что нам понадобятся два Sound Class. В Content Browser нажмите наAdd Newи выберитеSounds\Sound Class. Переименуйте Sound Class вS_Music_Class.

Создайте ещё один Sound Class и назовите егоS_Effects_Class.

Туториал по Unreal Engine. Часть 7: звук

Теперь нужно привязать каждый звук к Sound Class. Для начала мы сделаем это с музыкой. ОткройтеS_Musicи найдите разделSound. ИзменитеSound ClassнаS_Music_Class.

Туториал по Unreal Engine. Часть 7: звук

Сделав это, закройтеS_Music.

Следующими будут звуковые эффекты. Вместо того, чтобы открывать каждый звук по отдельности и привязывать его к Sound Class, мы можем сделать это одновременно. Сначала выберите следующие ассеты:

  • S_Footstep
  • S_Pop_Cue
  • S_Rain

Затемнажмите правой клавишей мышина одном извыбранных ассетов. ВыберитеAsset Actions\Bulk Edit via Property Matrix. При этом ассеты откроются в редакторе матрицы свойств.


Редактор матрицы свойств позволяет изменять общие свойства за один раз.

Перейдите в панель Details и разверните веткуSound. Для выбора Sound Class нажмите на значоксеткисправа отSound Class.

Туториал по Unreal Engine. Часть 7: звук

ВыберитеS_Effects_Class, а затем закройте редактор матрицы свойств.

Все звуки теперь находятся в соответствующем Sound Class. Далее мы создадим Sound Mix и настроим его с помощью Blueprints.

Создание и настройка Sound Mix

В Content Browser нажмите наAdd Newи выберитеSounds\Sound Mix. Переименуйте Sound Mix вS_Volume_Mix.

Чтобы управлять громкостью каждого Sound Class, мы будем использовать ползунки. Я уже создал виджет с двумя ползунками, чтобы вы могли его использовать. Перейдите в папкуUIи откройтеWBP_Options.

Туториал по Unreal Engine. Часть 7: звук

Чтобы настроить громкость, нам нужно использовать значение этих ползунков и передавать их в Sound Mix. Сначала мы сделаем это для музыки.

Переключитесь в режим Graph и перейдите в панель My Blueprints. В разделеVariablesвыберитеMusicSlider. Перейдите в панель Details и нажмите накнопкурядом сOn Value Changed.

Туториал по Unreal Engine. Часть 7: звук

При этом будет создано событиеOn Value Changed (MusicSlider). Это событие срабатывает, когда мы будем перемещать ползунок.

Туториал по Unreal Engine. Часть 7: звук

Теперь нам нужно задать громкостьS_Music_ClassвS_Volume_Mix. Для этого нам нужно использовать нодSet Sound Mix Class Override. Этот нод позволяет указать Sound Mix и Sound Class. Если Sound Class не находится в Sound Mix, то он будет добавлен. Если он уже есть в Sound Mix, то он будет обновлён.

Добавьте нодSet Sound Mix Class Overrideи выберите следующие опции:

  • In Sound Mix Modifier:S_Volume_Mix
  • In Sound Class:S_Music_Class
  • Fade in Time:0 (благодаря этому регулировка громкости будет выполняться мгновенно)
Туториал по Unreal Engine. Часть 7: звук

Затем соедините ноды следующим образом:

Туториал по Unreal Engine. Часть 7: звук

Повторите эти шаги дляEffectsSlider. Замените контактIn Sound ClassнаS_Effects_Class.

Туториал по Unreal Engine. Часть 7: звук

Теперь при изменении значения ползункаS_Volume_Mixбудет регулировать громкость соответствующего Sound Class.

Чтобы это заработало, нам нужно активировать Sound Mix.

Активация Sound Mix

В подобных случаях (когда громкость регулируется через UI) лучше активировать Sound Mix при запуске игры. Таким образом, Sound Class будет автоматически использовать регулировку громкости из Sound Mix. Однако ради простоты мы будем активировать Sound Mix внутри виджета.

Создайте нодEvent Pre Construct. Он подобен нодуEvent BeginPlay, используемому в Blueprints.

Туториал по Unreal Engine. Часть 7: звук

Чтобы активировать Sound Mix, нам нужно использовать нодPush Sound Mix Modifier. Создайте его и соедините сEvent Pre Construct. Затем задайтеIn Sound Mix ModifierзначениеS_Volume_Mix.

Туториал по Unreal Engine. Часть 7: звук

Благодаря этомуS_Volume_Mixбудет активироваться при спаунеWBP_Options.

Нажмите наCompileи закройтеWBP_Options. Нажмите наPlayи нажмите клавишуM, чтобы открыть ползунки. Двигайте ползунки, чтобы изменять громкость каждого Sound Class.

Туториал по Unreal Engine. Часть 7: звук

Куда двигаться дальше?

Скачать готовый проект можноздесь.

Как вы видите, работать со звуком в Unreal Engine 4 довольно просто. Если вы хотите узнать больше о системе звука, то изучитеофициальную документацию. Можно создавать другие интересные эффекты, добавляя реверберацию и эквалайзер. Кроме того, познакомьтесь с возможностями, которые появятся после выпусканового звукового движка!

Если вы хотите продолжать обучение, прочитайтеследующую часть, в которой я расскажу, как создавать эффекты частиц.

Автор перевода PatientZero

Поделится

Туториал по Unreal Engine. Часть 7: звук: 4 комментария

  1. Добрый день! Меня зовут Евгений Потапов.
    Заинтересовал ваш сайт roman-tashev.ru. Хочу его купить. По факту изучения статистики, я смогу назвать точную сумму которую я готов за него заплатить.
    Если вам интересна продажа вашего проекта, жду вашего ответа.
    С уважением,
    Евгений Потапов
    mr.evgenij-potapov@yandex.ru

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

    Наши услуги включают:

    1. Администрирование сайта.
    3. Администрирование хостинга.
    4. Контент-менеджмент.
    5. Дизайн и редизайн.
    6. Контроль работоспособности.
    7. Доработки существующего функционала.
    8. Внедрение новых инструментов и функций.
    9. Контроль за безопасностью проекта.
    10. Обучение и консалтинг.

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

    Если вы заинтересованы в ответственном подрядчике, который улучшит работу вашего сайта, не стесняйтесь связаться с нами. Мы готовы обсудить ваши потребности и предоставить подробную информацию о наших услугах.

    Контакты для связи:

    Email: tp_sale@wbhr.ru

    Telegram: @wbhr_bot

Добавить комментарий

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять