Небольшая заметка по озвучиванию проекта на Unity (Survival Shooter) посредством языка аудио-программирования Chuck и Open Sound Control (OSC).


В результате всех манипуляций, получился такой результат:



Все звуки генерируются “на лету” в Chuck’е. Wav-файлы не используются совсем. Для генерации подобия голоса использовано решение, написанное Perry Cook’ом для Chuck’а, суть решения частично объясняется в курсе Physics-Based Sound Synthesis for Games and Interactive Systems. В качестве выстрела использована обычная пилообразная волна с “падающим” питчем и добавлением хорус-эффекта.


Как это работает


Для посылки OSC-сообщений использованы наработки Mike Heavers’а. Их нужно импортировать в Unity-проект: плагин Osc.cs, плагин UDPPacketIO.cs, скрипт OSCTestSender.cs. К каждому объекту, который издаёт звук, крепим эти плагины и переработанный скрипт — для каждого он свой, изменяются адреса OSC-сообщений.


Всего в проекте 9 источников звука:


  • Player Shoot
  • Player Hurt
  • Player Death
  • Zombunny Hurt (маленький зелёный моб)
  • Zombunny Death
  • Zombear Hurt (маленький красный моб)
  • Zombear Death
  • Hellephant Hurt (большой жёлтый моб)
  • Hellephant Death

Принятие OSC-сообщений в среде Chuck делается с помощью класса OscIn. Указываем соответствующий порт (oin.port) и адрес (oin.addAddress). Далее при поступлении osc-сообщения генерируется звук.


На стороне Chuck сделано 5 отдельных проектов, каждый из которых принимает сообщение по своему порту и генерирует соответствующий звук(и):


  • oscin_shoot
  • oscin_player_hurt
  • oscin_zombunny_hurt
  • oscin_zombear_hurt
  • oscin_hellephant_hurt

Для теста нужно сначала запускать все программы Chuck — делаем отдельный файл запуска init.ck. Затем запускаем проект Unity. Играем, OSC-сообщения генерируются как только происходит нужное событие, Chuck принимает сообщения и генерирует звук.


Наглядно это можно представить схемой:


Unity connected to Chuck via Open Sound Control

Единственная проблема с которой я столкнулся — это переключение OSC-порта на другого моба. Если спаунится много персонажей, например 3 зомбо-кролика, 2 зомбо-медведя, то звук будет проигрываться только у первого заспаунившегося моба соответствующего типа. Переключение канала произойдёт только после убийства этого первого моба. Пока быстрого решения не нашёл.


Надеюсь было интересно, если у кого-то есть интересные ссылки по данным темам (OSC, генерация звука и т.п.) — пожалуйста, поделитесь в комментариях.


Спасибо за внимание!

Поделиться с друзьями
-->

Комментарии (6)


  1. KumoKairo
    15.01.2017 14:16
    +1

    Для затравки хорошо, но сразу возникает много вопросов:
    1. Хочется немного более подробно про сам механизм генерации звуков, немного бэкграунда по ChucK и OSC. (Хотя бы вводные слова)
    2. На какие платформы можно применить данный подход
    3. Если можно на мобилки, то как там с производительностьюю
    4. Может есть какая-то реализация на C#/.NET для того чтобы исключить это взаимодействие через сокеты и прочие свистопляски?


    1. headshotlab
      15.01.2017 15:36
      +1

      На 2-3-4 вопросы не могу ответить, к сожалению. Просто не обладаю достаточным опытом/информацией. На сколько я понял, сама тема активного использования OSC достаточно молодая, информации о реальных проектах не много, а уж про технические подробности тем более. Изначально ставил себе задачу подключить внешнюю генерацию звуков к unity. На данном этапе получилось вот так (Unity->OSC->Chuck). Даже не представляю как это всё забилдить в один проект, что бы поиграть не в движке.
      Сам Chuck — это один из языков программирования аудио (есть ещё pure data, max/msp и т.д.). Сделан на основе C++. Суть в том, что в нём уже есть минимальная библиотека инструментов работы со звуком (генераторы сигналов, эффекты, механизмы проигрывания аудио-файлов и т.п.), т.е. их не надо программить. Дальше уже из них делаются разнообразные решения. Активно используется всякими гиками типа Stanford Laptop Orchestra (для генерации звука) и Karmetik Machine Orchestra (для обработки сигналов с реальных инструментов и посыла инфы роботам что играть).
      OSC изначально должен был стать заменой MIDI-протокола, но в итоге отпачковался в отдельную ветку и используется для соединения различных мультимедийных устройств (всё вместе — «internet of things», по-моему, называется). В отличие от midi способен передавать и string и int и float сообщения. Судя по вики он ещё и работает быстрее. Думаю, со временем появятся более гуманные решения (а не то что я описал) по использованию OSC в играх, но пока всё это вот в таком состоянии.


    1. Leopotam
      15.01.2017 15:39
      +1

      OSC — это сетевое взаимодействие через UDP сокет посредством управляющих сообщений в определенном формате. Года 3 назад требовалось сделать нечто подобное, только в обратном направлении — получать команды с midi-синтезатора по сети и реагировать на них в 3д-сцене. OSC часто применяется в разных световых шоу для синхронизации с музыкой в реалтайме.


    1. Leopotam
      15.01.2017 15:41
      +2

      2. OSC — на любые, где можно завести UDP сокеты.
      3. Аналогично, если сможете пробивать NAT или будете крутить в локалке — проблем быть не должно.
      4. Не помню, что конкретно использовал, но вроде вот это: https://github.com/ValdemarOrn/SharpOSC


  1. znsoft
    15.01.2017 14:44

    Исходя из своего демосценерского прошлого, давно думал сделать подобное для Unity. Генерировать wav при первом запуске игры и в результате снизить использование процессора на постоянную генерацию звука.


  1. KislyFan
    15.01.2017 14:44

    видел чудеса техники но такого…
    image