Following the instructions up to page 179 in the latest pdf, when I deploy CatNap to either a simulator or to my iPad, the animation for swinging the cat’s tail doesn’t seem to be triggered.
I have noticed the following, which may be relevant:
The cat’s tail does swing when I press animate in the Cat.sks action editor.
The cat’s tail does not swing when I press animation in GameScene.sks editor.
Changing the startup up scene to Cat.sks shows the swing action as expected.
The provided “final” project works fine - but I can’t see any differences!
Adding an action (or even editing one) break things - no actions are then being run on deploy. Deleting the new action doesn’t fix the problem!
No errors reported on the console.
It looks like a problem with Xcode - but if anyone has any suggestions - greatly appreciated!
When you get to pages 216-217 and add create the CatNode.swift file you can add isPaused=false
either before or after print("cat added to scene")
in didMoveToScene
Actually I had the same problem for catCurl and catAwake, both in the CatNode.swift file.
I found in both cases adding isPaused = false after the move(toParent: self) worked.
I wish I had looked here first before spending hours on this issue.
After reading this thread, I ended up enumerating the nodes in the didMove override in GameScene.swift:
enumerateChildNodes(withName: "//*") { (node, stop) in
print("\(String(describing: node.name)) paused: \(node.isPaused)")
if node.isPaused {node.isPaused = false}
}
It showed that all the nodes in the cat reference had isPaused = true. Changing the cat_body node changed its child nodes as well, so it is the only one that needs to be changed.
Was there ever a fix for the Xcode glitch? I am not at the catNode.swift file creation yet and am trying to see if I can get this to work before heading into the next section.
I have to admit this is a problem for me too. I also noticed that along with the tail not swinging the cat wouldn’t actually purr until one of the blocks had been removed. The mouth would move and all that but there was no sound. Once a block had been removed the purring sound kicked in. Weird.
I’m very green when it comes to all this but if Xcode is setting isPaused to true then is there a way to change it to false earlier than at catNode?
I’m in the same boat @airtower, haven’t yet gotten to the point where I write a .swift file for this. I’m blown away that there’s no “isPaused” option in the Properties Inspector or anywhere in the Scene Editor for that matter… That you actually need to fix this with code.
I figured out the issue. When I created my project, I had the “Integrate GameplayKit” selected. As a result Xcode setup viewDidLoad() in GameViewController with the code with GKScene and subsequently sceneNode instead of SKScene and scene (shown below). Once I corrected viewDidLoad() to match the Challenge viewDidLoad(), the tail wags when running as it should in Chapter 7.
EDIT:
The difference lies in the isPaused property of the SpriteNodes.
And this property seems to set itself depending on whether or not you moved/altered a referenced Sprite since you last build/ran CatNap.
I figured out a way to be able to modify Sprites between builds, it’s a pain but it works.
How to keep the Sprite Nodes from Pausing
The Key is to not move a Sprite that you just placed in, until AFTER it’s first build.
In Cat.sks file - (or any sks file you want to reference)
Set up scene size. 380 x 440 points
Save.
Page 167 details how to set it up.
In GameScene.sks
Place a Reference object anywhere in the scene.
Save.
Page 169 has instructions
Name cat_shared
Reference Cat
Position 1030, 1045
zPosition 10
In Cat.sks
Place a Colour Sprite object into the scene Important! Don’t move it once you drop it in the scene - that will cause the Sprite’s isPaused property to insta be set to true!
If you moved the Sprite: delete it and drop a new one in.
Set it’s colour to System Green Colour (or any colour except red to avoid confusion)
Place a Rotate Action object in the timeline for that Sprite and have it repeat via ∞ infinity loop.
Page 177 has details.
Build/Run - the green square Sprite should rotate. isPaused = false
Temp Cat Body
Drag in 4 more Colour Sprites into the scene.
Build / Run - the Green Sprite should still be rotating.
These 4 Red Sprites will be
A Temporary Cat Body
name it temp_body, texture cat_body, X 22, Y -112
Cat Head
Name cat_head, Parent temp_body, texture cat_head, X 18, Y 192
Cat Mouth
Name mouth, Parent cat_head, texture cat_mouth, X 6, Y -67
Cat Eyes
Name eyes, Parent cat_head, texture cat_eyes, X 6, Y 2
Page 167 - 168 details their properties.
Build / Run - Green Sprite should still be rotating, and all the Sprites should not be Paused. Now’s a great time to commit changes to your Git repository.
Tail
Place a Colour Sprite object into the scene - it will be Red.
Place RotateToAngle Action on the Sprite
Page 173 has details.
Duration: 2, Degrees: 5
Place another RotateToAngle Action on the Sprite’s timeline
Duration: 1.5
Select Both and repeat them forever via an ∞ infinity loop
Page 177 has details.
If Green Sprite stops spinning now or at any point, it’s a good indicator that your other nodes will no longer animate - that’s probably going to happen, which is why we made a temp_body from the get go.
Name the Red Sprite tail, set it’s texture to cat_tail.
Build and Run, the tail should look like a tail and be swinging.
Set the tail’s parent to temp_body, Position -206, -70, zPosition -1
Build/Run - the Tail will probably stop moving. That’s ok. If it’s swinging You’re done!
Cat Body
If the tail stopped swinging - Set the tail’s parent back to SKScene_0.
You can stop here if you don’t mind that the tail’s parent isn’t the cat_body.
The last few steps address this.
Delete the Rotate Action on the Green Sprite, because this Sprite is going to be the cat_body. Note: Only use this Green Sprite if it has been spinning up until this point.
If your Green Sprite had stopped spinning a few steps above, replace it with a new Colour Sprite.
Set the name of the Green Sprite to cat_body, texture cat_body, X 22, Y -112
Set tail’s parent to cat_body,
Set cat_head’s parent to cat_body
Build/Run
That tail should still be swinging like a boss.
Things should be easier from here on out because it seems this bug only happened when modifying the Sprites in the file referenced, meaning I could freely move the SKEditorReferenceNode to Cat in GameScene without issue.
After reading through the various solutions and googling similar behaviour in general when using scene builder in Xcode, the simplest solution that I found to work was simply to set the .isPaused property to false. HOWEVER, I did find from Googling, that for some, this only works after setting the property to true. So,
scene.isPaused = true
scene.isPaused = false
I also found that for some, you might need to set the property on the view rather than the scene
I had the same problem and typed view.isPaused = true, and then
view.isPaused = false, in the viewDidLoad() , in GameViewController.swift and it
WORKED!
I was getting stressed out trying to figure out what I did wrong! This book really needs an update to fix the code!
Hey everyone! This issue still seems to occur in 2020. For those of you that don’t want to skip ahead and add stuff in the CatNode file you can add this is in the didMove(to view:) function in your GameScene.swift:
if let cat = childNode(withName: "cat_shared") { // 1
for item in cat.children { // 2
item.isPaused = true // 3
item.isPaused = false
}
}
Did anyone ever figure this out? It’s still a problem as of XCode 11.5 and it’s driving me crazy! The only way I can get it to work is to set isPaused = true and then isPaused = false. Why on earth would you need to do that? It has to be a bug somewhere?