使用 fileNamed 初始化 SKAudioNode 返回 nil
Posted
技术标签:
【中文标题】使用 fileNamed 初始化 SKAudioNode 返回 nil【英文标题】:Initializing SKAudioNode using fileNamed returns nil 【发布时间】:2016-04-09 15:16:52 【问题描述】:这是我第一次使用 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
说:在展开可选值时意外发现 nil。
我确实确保了以下内容
ABC.caf 在我的项目中,并在复制包资源中列出。 拼写正确。现在我还应该在哪里检查错误?
编辑:
这是我的配置信息:
Xcode 7.3 装有 ios 9.3.2 的 iPhone 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)
现在我的应用不再崩溃,但没有声音。有什么想法吗?
附:在我上次编辑该问题几分钟后,我尝试将该方法中的所有内容替换为:
runAction(SKAction.playSoundFileNamed(name, waitForCompletion: false))
还是没有声音。可能是声音文件有问题?
【问题讨论】:
您使用的是 Xcode 7.3 对吗? ***.com/q/36273271/3402095 对我来说,在使用 Xcode 7.1.1 时,即使我提供了错误的文件名,backgroundMusic
也不会以 nil 结尾,而是带有某种“空”SKAudioNode。不过,它不会崩溃。顺便问一下,您是否尝试过重新添加声音?你知道,从项目中删除它,然后转到 Product-> clean,然后再次将相同的声音拖到项目中并将其添加到 Copy Bundle Resources 部分......只是看看这是否与一些奇怪的缓存问题无关(但是我对此表示怀疑)。
@Whirlwind 是的,我在 Xcode 7.3 上。我试图删除音乐文件并将其重新添加回项目,并执行了清理。它仍然崩溃,因为它在展开可选时发现 nil。
您是否尝试使用“ABC”而不是“ABC.caf”?
@GoodDoug 我试过了,同样的错误。
您是否检查以确保该文件包含在您的构建中?仅仅添加到项目中可能还不够好。另外,文件名区分大小写,您是否将文件命名为 SpaceGame.caf 而不是 spaceGame.caf
【参考方案1】:
我刚刚遇到了这个问题。显然,它现在只适用于局部变量。以下代码有效。
var background:SKAudioNode!
override func didMoveToView(view: SKView)
let bg = SKAudioNode(fileNamed: "bg.mp3")
addChild(bg)
background = bg
【讨论】:
非常好,+1,但为什么?【参考方案2】:我用上面 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 的耳机插孔有问题,也许开关也有问题。【参考方案3】:我遇到了与SKAudioNode(fileNamed:)
类似的问题,从自动完成和我遇到的问题来看,有两个具有相同参数签名的不同初始值设定项,一个返回SKAudioNode
,一个返回SKNode
和我不知何故弄错了。我改用SKAudioNode(url:)
(使用Bundle.main.url(forResource:withExtension:)
获取URL),一切都按预期工作。
【讨论】:
【参考方案4】:已经有好几年了,但是我发现构造函数 SKAudioNode() 需要一些时间来加载声音——不管它有多大。即使是 50 kByte 的小声音文件也需要 0.25 秒才能加载。在初次使用之后,所有后续的声音加载只需要一小部分时间。 我猜 SpriteKit 会对应用文件中的所有声音进行一些缓存。
所以要解决第一个延迟声音的问题:像我在菜单中一样播放它们 - 零音量和零长度。
我的实验表明,在 Xcode 11 模拟器初始化时,预播放 20 个声音文件也需要 0.25 秒。所以我再次猜测预播放一个(!)声音会告诉 iOS 将所有声音文件预加载到内存中。
【讨论】:
以上是关于使用 fileNamed 初始化 SKAudioNode 返回 nil的主要内容,如果未能解决你的问题,请参考以下文章