Инициализация 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:)
) и все заработало как положено.