Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get SKAction(name:) to work reliably?

I've been working through the DemoBots example and having a lot of trouble getting it to work on all devices.

https://developer.apple.com/library/prerelease/ios/samplecode/DemoBots/Introduction/Intro.html

The current problem I'm having is that on an iPad Mini the app launches but crashes when loading animations. It crashes in AnimationComponent.swift on the line that loads an action from a file:

let bodyAction: SKAction?  
if let name = bodyActionName {
    // crash here  
    bodyAction = SKAction(named: name)  
}  
else {  
    bodyAction = nil  
}  

Debugging the app reveals that its trying to load an SKAction called "ZappedShake" but crashing with an array out of bounds exception.

On an iPhone 5S it runs fine. My best guess is its race condition with the faster iPhone 5S is loading the file with the action serialized in it, and by the time execution reaches this point the action is available. But on the single core older iPad the file is not yet loaded and the call fails.

Both are real hardware running iOS9 13A4325c, compiled on XCode Version 7.0 beta 4 (7A165t).

Making the problem more difficult is that I can't see where the file that apparently creates the "ZappedShake" - ReferenceActions.sks - is actually loaded. Its referred to by ReferenceScene.sks but nowhere in any of the code or anywhere else in the project can I see that file being referred to.

Is there some sort of name convention magical file loading mechanism for SKActions? Why does it work on the iPhone 5S and not on the iPad?

UPDATE: Found more on this here: http://asciiwwdc.com/2015/sessions/604

Also this year we focused on referencing and instancing. We know you spend a lot of time designing high-quality content and animations for your games and we want you to let you reuse that content anywhere where you would like to.

We're allowing you to create serialized data files for your nodes and your actions and then add them as a reference instead of just loading them into your scene.

This way, every time you make a change to the source asset that is automatically reflected in the content of your game.

How do I do this for nodes? For nodes I design part of my scene, maybe a background element, or some scenery in our editor with an Xcode and then I can just drag-and-drop those files into my main scene in Xcode and it will automatically create a reference and it is all set up for you.

If you want to do this in code you can as well, you can manually construct an SKReferenceNode, assign it a file name or even a URL and when that content is first presented in your game we'll load in that content based on the latest version of the file that's in your bundle. We can also do the same thing for actions. With actions go check out our great new action editor and beyond creating and composing the actions in Xcode you can give all them names.

These names are the key to using them in your game. We have added a selector to SKAction called actionNamed. This works just like it does for SKTexture and textureNamed.

You pass in the name of the action you want. We're going to automatically look inside of your app bundle in all of the serialized action files, find the one with the appropriate name and then surface that to the application.

This looks great but I can't find any documentation on it, or figure out how to debug it when it goes wrong.

like image 311
Sez Avatar asked Nov 09 '22 06:11

Sez


1 Answers

It's not you, it's iOS. There's a bug with action references affecting 32-bit devices (like the iPad Mini.)

This issue has been fixed in iOS 9.2 Beta 1, according to this thread on the Apple developer's forum: https://forums.developer.apple.com/thread/17267

Try running on a more recent 64-bit device (like iPhone 6) in the simulator. Or try upgrading your iPad Mini to iOS 9.2 Beta 1. Or just wait for the next iOS release to fix the problem.

like image 84
kevcol Avatar answered Nov 14 '22 23:11

kevcol