Donate with PayPal button New New

+ Ответить в теме
Показано с 1 по 8 из 8

Тема: Звуки с ожиданием

  1. #1
    Пользователь Аватар для Эрендир
    Регистрация
    13.01.2010
    Страна
    Адрес
    Я Бот, живу в сети :)
    Возраст
    40
    Сообщений
    6,303

    Script Звуки с ожиданием

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

    Как известно, для проигрывания звуков в Trainz есть функция у абстрактного класса World
    Код:
    PlaySound(Asset asset, string filename, float volume, float minDistance, float maxDistance, GameObject target, string attachmentPoint, bool looping);
    До Trainz 2012 это функция возвращала float значение соответствующее длине проигрываемого звукового файла. Достаточно было это значение только подставить в Sleep, и всё прекрасно работало.
    Однако, с введением в Trainz 2012 эффекта Доплера длина звукового файла фактически перестала быть константой. В связи с этим, N3V Games отказались от привычной работы функции PlaySound, которая перестала возвращать значение соответствующее длине проигрываемого звукового файла. Значит, привычный способ реализации звуков, особенно зацикленных, больше не подходит. Как быть? Выходит, что знать длину звукового файла нам надо заранее. Есть разные способы реализации этого подхода, однако здесь я хочу поделиться тем способом, который я сделал для себя. Этот способ, на мой взгляд, наиболее универсален.

    Первое что необходимо сделать, так это написать обёртку для функции PlaySound. Выглядеть она будет вот так:
    Код:
      public final void PlaySoundAndSleep(Asset srcAsset, string soundFile, float volume, float minDistance, float maxDistance, GameObject srcObject, string att, float subtime)
      {
        World.PlaySound(srcAsset, soundFile, volume, minDistance, maxDistance, srcObject, att);
        Soup wavdb = srcAsset.GetConfigSoup().GetNamedSoup("extensions").GetNamedSoup("sound-length-base");
        me.Sleep(wavdb.GetNamedTagAsFloat(soundFile, 10.0) - subtime);
      }
    Набор параметров здесь такой же, как и у оригинальной функции, кроме параметра subtime:
    • srcAsset - ссылка на актив, который содержит звуковые файлы. Одним словом, это наша библиотека звуков.
    • soundFile - Путь к звуковому файлу. Напоминаю, что это относительный путь от корня актива (где лежит config.txt)
    • volume - громкость проигрываемого звука. Значения от 0.0 - 1.0. Хочу обратить внимание, что 1.0 - это оригинальная громкость звукового файла. Значения выше 1.0 ставить нет смысла, ибо громкость выше не станет.
    • minDistance - расстояние в метрах от точки проигрывания звука, на котором затухание звука будет отсутствовать (громкость будет равна заданной в volume)
    • maxDistance - расстояние, на котором звук затухнет полностью. Это значение должно быть больше, чем minDistance
    • srcObject - это непосредственно объект, в котором находится точка привязки к звуку. (если скрипт у нас в этом объекте, то me)
    • att - имя точки привязки, от которой будет исходить звук. (имеет формат a.name)
    • subtime - дополнительный параметр позволяющий сокращать или удлинять длину звука для более плавного перехода одного звука к другому или в зацикленных звуках. Задаётся в секундах. Положительно значение уменьшает ожидание, отрицательное увеличивает.

    Это функцию нужно просто скопировать в тот скрипт, откуда будет производиться проигрывание звука.

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



    В архиве папка с 3-мя файлами. Надо эту папку распаковать,звуковые файлы кинуть в неё же. Затем запустить run.cmd. После того, как программа завершиться, необходимо открыть блокнотом файл len.txt. В нём будут все длины файлов уже в том виде, в котором их необходимо будет вставить в config.txt файл звуковой библиотеки

    Перейдём к config.txt файлу. В нём необходимо создать стандартный блок расширений extensions. Выглядит это вот так
    Код:
    extensions
    {
    
    }
    Затем, внутри этого блока необходимо создать блок, который и будет содержать длины звуковых файлов. Это будет выглядеть так
    Код:
    extensions
    {
      sound-length-base
      {
    
    
      }
    }
    И уже в блок sound-length-base необходимо вставить то, что получилось в файле len.txt. Конечный вариант файла конфигурации будет выглядеть так
    Код:
    extensions
    {
      sound-length-base
      {
        compressor_run.wav                  "1.435"
        compressor_start.wav                "0.992"
        compressor_stop.wav                 "0.627"
        fuelpump.wav                        "8.852"
        oil_pump_run.wav                    "2.005"
        oil_pump_start.wav                  "0.747"
        oil_pump_stop.wav                   "1.569"
        engine_start.wav                    "13.550"
        engine_stop.wav                     "6.339"
      }
    }
    Останется только получить актив библиотеки в скрипте, который и будет передан в качестве первого параметра для модифицированной функции.
    Если звуки у нас в том же активе в котором скрипт, то это можно сделать вызвав функция GetAsset. Она вернёт ссылку на актив, в котором выполняется скрипт.
    Если же звуки лежат в отдельном активе, то его необходимо прописать в kuid-table config.txt того актива, в котором выполняется скрипт, и с помощью функции FindAsset вытащить на него ссылку.
    Подробнее об этих функциях можно узнать на wiki разработчиков


    Надеюсь, что эта статья поможет начинающим скриптерам .... и не только
    Последний раз редактировалось jim_spb; 21.06.2020 в 04:25.


  2. #Trainz
    Реклама
    Регистрация
    Постоянная
    Адрес
    Весь мир
    Возраст
    2010
    Сообщений
    Много

    Donate with PayPal button N3v New New

     

  3. #2
    Заблокирован Аватар для leha ya !
    Регистрация
    22.07.2015
    Страна
    Адрес
    ДВЖД
    Сообщений
    2

    По умолчанию

    подскажите пожалуйста как можно прикрутить звуки дизеля от скриптового локомотива к локомотиву с простым запуском и расходом !?

  4. #3
    Пользователь Аватар для ArtyemLavrov
    Регистрация
    28.07.2015
    Страна
    Адрес
    Архангельск
    Возраст
    34
    Сообщений
    142

    По умолчанию

    Для более похожей замены World.PlaySound, может кому поможет:
    Код:
    float World_PlaySound(Asset srcAsset, string soundFile, float volume, float minDistance, float maxDistance, GameObject srcObject, string att) {
        World.PlaySound(srcAsset, soundFile, volume, minDistance, maxDistance, srcObject, att);
        Soup wavdb = srcAsset.GetConfigSoup().GetNamedSoup("extensions" ).GetNamedSoup("sound-length-base");
        return wavdb.GetNamedTagAsFloat(soundFile, 10.0));
    }

  5. #4
    Пользователь Аватар для TRam_
    Регистрация
    22.09.2009
    Возраст
    34
    Сообщений
    16,432

    По умолчанию

    Цитата Сообщение от ArtyemLavrov Посмотреть сообщение
    Soup wavdb = srcAsset.GetConfigSoup().GetNamedSoup("extensions" ).GetNamedSoup("sound-length-base");
    лучше её получить заранее 1 раз, и потом везде использовать.

  6. Сказали спасибо: (3)


  7. #5
    Пользователь Аватар для ArtyemLavrov
    Регистрация
    28.07.2015
    Страна
    Адрес
    Архангельск
    Возраст
    34
    Сообщений
    142

    По умолчанию

    Цитата Сообщение от TRam_ Посмотреть сообщение
    Сообщение от ArtyemLavrov
    Soup wavdb = srcAsset.GetConfigSoup().GetNamedSoup("extensions" ).GetNamedSoup("sound-length-base");
    лучше её получить заранее 1 раз, и потом везде использовать.
    А вдруг разные библиотеки звуков?

  8. #6
    Пользователь Аватар для TRam_
    Регистрация
    22.09.2009
    Возраст
    34
    Сообщений
    16,432

    По умолчанию

    ArtyemLavrov, конфиги в trainz "на лету" в процессе игры не редактируются. А то что ты предполагаешь (что у разных локов объект скрипта подгружается один) - в корне не верно, каждая секция локомотива подгружает и инициализирует свой собственный экземпляр класса со своим собственным рефференсом на свою звуковую бибилотеку и её конфиг.
    Последний раз редактировалось TRam_; 15.12.2016 в 19:48.

  9. #7
    Пользователь Аватар для ArtyemLavrov
    Регистрация
    28.07.2015
    Страна
    Адрес
    Архангельск
    Возраст
    34
    Сообщений
    142

    По умолчанию

    Ты меня не понял. Ладно, проехали.

  10. #8
    Пользователь Аватар для kemal
    Регистрация
    22.10.2009
    Страна
    Адрес
    Казань / 793км
    Возраст
    36
    Сообщений
    3,567

    По умолчанию

    Тогда подгрузить суп для каждой.

+ Ответить в теме

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения