Инициализация SKAudioNode с использованием fileNamed возвращает nil

Это первый раз, когда я использую SKAudioNode. Сначала я объявил недвижимость в верхней части моего GameScene учебный класс:

var backgroundMusic: SKAudioNode!

Теперь я добавил вспомогательный метод:

func playBackgroundMusic(name: String) {
    if backgroundMusic != nil {
        backgroundMusic.removeFromParent()
    }

    backgroundMusic = SKAudioNode(fileNamed: name)
    backgroundMusic.autoplayLooped = true
    addChild(backgroundMusic)
}

Теперь я назвал этот метод так:

playBackgroundMusic("ABC.caf")

В этой строке выдается фатальная ошибка:

backgroundMusic.autoplayLooped = true

Говоря: неожиданно найден ноль при развертывании необязательного значения.

Я убедился, что следующее

  • ABC.caf находится в моем проекте и указан в ресурсах комплекта копий.
  • Это написано правильно.

Теперь, где еще я должен проверить на ошибки?

РЕДАКТИРОВАТЬ:

Вот моя информация о конфигурации:

  • Xcode 7.3
  • iPhone с iOS 9.3.2
  • Симулятор с iOS 9.3

И устройство, и симулятор не работают.

EDIT2:

Я изменил свои коды на следующее:

func playBackgroundMusic(name: String) {
    if backgroundMusic != nil {
        backgroundMusic.removeFromParent()
    }

    let temp = SKAudioNode(fileNamed: name)
    temp.autoplayLooped = true
    backgroundMusic = temp
    //backgroundMusic = SKAudioNode(fileNamed: "SpaceGame.caf")
    //backgroundMusic.autoplayLooped = true
    addChild(backgroundMusic)
}

Теперь мое приложение больше не падает, но в нем нет звуков. Есть идеи?

PS Через несколько минут после того, как я в последний раз редактировал этот вопрос, я попытался заменить все в этом методе на:

runAction(SKAction.playSoundFileNamed(name, waitForCompletion: false))

Все еще нет звука. Возможно проблема со звуковым файлом?

2 ответа

Я только столкнулся с этой проблемой. По-видимому, теперь он работает только с локальными переменными. Код ниже работал.

var background:SKAudioNode!

override func didMoveToView(view: SKView) {
    let bg = SKAudioNode(fileNamed: "bg.mp3")
    addChild(bg)
    background = bg
}

Я исправил эту проблему с кодом, который я поместил в EDIT2 выше:

func playBackgroundMusic(name: String) {
    if backgroundMusic != nil {
        backgroundMusic.removeFromParent()
    }

    let temp = SKAudioNode(fileNamed: name)
    temp.autoplayLooped = true
    backgroundMusic = temp
    //backgroundMusic = SKAudioNode(fileNamed: "SpaceGame.caf")
    //backgroundMusic.autoplayLooped = true
    //addChild(backgroundMusic)
    runAction(SKAction.playSoundFileNamed(name, waitForCompletion: false))
}

Для отсутствия звука просто убедитесь, что боковой переключатель на вашем iPhone не горит красным.

Прошло несколько лет, но я обнаружил, что конструктору SKAudioNode() требуется некоторое время для загрузки звука - независимо от его размера. Даже небольшой звуковой файл размером 50 кбайт загружается за 0,25 секунды. После первоначального использования все последующие загрузки звука занимают лишь часть этого времени. Я предполагаю, что SpriteKit выполняет кеширование всех звуков в файле приложения.

Итак, чтобы решить проблему первого задержанного звука: воспроизведите их, как в меню - с нулевой громкостью и нулевой длиной.

Мои эксперименты показывают - предварительное воспроизведение 20 звуковых файлов также занимает 0,25 секунды в симуляторе Xcode 11 для инициализации. Итак, я снова предполагаю, что предварительное воспроизведение одного (!) Звука сообщает iOS о необходимости предварительной загрузки всех звуковых файлов в память.

У меня была аналогичная проблема с SKAudioNode(fileNamed:) и это выглядело из автозаполнения и из проблем, которые у меня были, например, есть два разных инициализатора с одинаковой сигнатурой параметра, один из которых возвращает SKAudioNode и один возвращающийся SKNodeи я как-то ошибся. Я перешел на использованиеSKAudioNode(url:) вместо этого (получение URL с помощью Bundle.main.url(forResource:withExtension:)) и все заработало как положено.

Другие вопросы по тегам