Синтезатор на Unity 3D

от автора

Учебные материалы для школы программирования. Часть 13

Предыдущие уроки можно найти здесь:

При тематическом планировании уроков, мы сталкиваемся с интересной задачкой: в нашей группе учатся и мальчишки и девчонки. У них разные вкусы, разные любимые герои, жанры. И если все занятия будут на тему гонок или Silent Hill — ряды девочек на ваших занятиях, — поредеют. Эту ситуацию мы решаем двумя способами:

  • спрашиваем мнение ребят и проводим голосование на уроке. Да-да, только дети смогут сделать вашу программу интересной, поэтому их мнение действительно значимо. Не для галочки. Опрос и обсуждение важно проводить регулярно, ибо все группы разные, темы меняются от возраста к возрасту, меняются в зависимости от того, во что сейчас играют и что смотрят в кино;

  • чередуем и комбинируем. Мы стараемся чередовать «спокойные» и «агрессивные» проекты. Например, в этом месяце мы делаем лабиринт ужасов, но после его защиты — приступаем к созданию острова с лесом и домиком. При комбинировании, мы предлагаем всем ребятам уделить внимание визуальной составляющей (раскрасить, добавить элементов, составить композицию и пр.), и девочки с большим энтузиазмом берутся за такую задачу.

Сегодня мы сделаем проект из категории: спокойный, для девчат. Мальчишкам тоже хорошо заходит — особенно момент, когда в конце урока получается звуковая какофония =)

Рассмотрим следующие темы:

  • выставление вращения объектов в локальной системе координат посредством конверсии из углов Эйлера в кватернионы;

  • события объектов OnMouseEnter и OnMouseExit;

  • метод POW класса Mathf — возведение в степень;

  • парсинг float из имени объекта через системный метод Parse ;

  • стек постэффектов от Unity Technologies;

  • функция движка RequireComponent.

Особое внимание обратим на:

  • изменение скорости воспроизведения и высоты звука через Pitch;

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

Порядок выполнения

Создаётся новый проект, импортируется приложенный ассет, открывается сцена piano (в проекте заранее заготовлена сцена, ключевыми объектами которой являются клавиши, расположенные на сцене в «Пианино/Клавиши»).
Клавиши пронумерованы в соответствии с полутонами, начиная с ноты «до» и заканчивается нотой «фа» следующей октавы, т.е. «до», «до диез», «ре», «ре диез», «ми», «фа» и т.д.

Клавиши расположены с начала октавы в той же последовательности, что и на реальном пианино.

Весь проект умещается в один скрипт. Полный листинг содержит пояснения:

using System.Collections; using System.Collections.Generic; using UnityEngine; using System;  [RequireComponent(typeof(AudioSource))] // необходимо для того, чтобы скрипт требовал установленный аудиосорс  public class Piano : MonoBehaviour {  	public KeyCode Key; // энумератор для выбора клавиши клавиатуры, на которую реагирует скрипт 	AudioSource src; // Аудиосорс, приват-переменная       void Start () { 		src = GetComponent<AudioSource>(); // получаем аудиосорс         src.pitch = Mathf.Pow(1.059462f, float.Parse(name) - 1f); // высота звука равна 1.059462f в степени (имя_клавиши - 1). 	} 	     void Update () { // Для уменьшения отклика стоит использовать FixedUpdate 		if (Input.GetKeyDown(Key)) { // если нажали клавишу. 			playNote(); // играем         }          if (Input.GetKeyUp(Key)) { // если отпустили клавишу. 			stopNote(); // не играем         } 	}      	private void OnMouseEnter() { // если мышь над коллайдером клавиши         playNote(); // играем 	}      	private void OnMouseExit() { // если мышь вышла из коллайдера клавиши          stopNote(); // не играем 	}      	private void playNote() { // играем 		transform.localRotation = Quaternion.Euler(-3, 0, 0); // ставим локальный угол поворота на -3 градуса по Х 		src.Play(); // Включаем звук с начала 	}      private void stopNote(){ // не играем 		transform.localRotation = Quaternion.Euler(0, 0, 0); // ставим локальный угол поворота на 0 градусов по всем осям     	src.Stop(); // Останавливаем звук     } }

Особое внимание стоит уделить строке:

src.pitch = Mathf.Pow(1.059462f, float.Parse(name) - 1f);//высота звука равна 1.059462f в степени (имя_клавиши - 1).

Число ​1.059462 ​высчитано математически и является простой заменой логарифмической функции, делящей одну октаву на 12 полутонов. Таким образом, каждый последующий полутон в 1.059462 раза выше предыдущего по частоте, что при количестве 12 полутонов даёт умножение частоты на 2 с ошибкой в 0.00003 Гц на октаву. С учётом того, что динамический диапазон нашего пианино не превышает полторы октавы, звук практически не искажается.

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

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

А всем аудиосорсам в качестве output установлен мастер-канал аудиомикшера.

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

Далее, немного оформляем сцену и добавляем следующие эффекты:

  • SSAO — подчеркнёт тени между клавишами, добавит глубины картинке.

  • Bloom — высветлит светлые участки ещё сильнее, сделает картинку более приятной на глаз, интенсивность нужно выбрать довольно низкую.

  • Антиалиасинг, чтобы убрать пикселизацию.

  • Винетка, чтобы затенить края, выделив основной объект.

    Можно добавить SSR, для легкого отражения на вертикальных плоскостях, что немного улучшит картинку.

Готово!

ссылка на оригинал статьи https://habr.com/ru/post/551516/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *