Animations of SpriteKit overlay on SceneKit stops when SceneKit animations stop - ios

I guess someone must have asked this before, but I can't find it right now so in the meanwhile here goes.
Animations of SpriteKit overlay on SceneKit stops when SceneKit animations stop. This is unexpected. It's like the whole SCNView and its children goes into sleep as soon as the 3D contents don't move. How can I make the spritekit scene animate independently of what the scenekit scene does?
Update: I have confirmed that if I add a simple 3D box that rotates indefinitely and keep it in the view somewhere, the 3D scene does not "sleep" and neither does the overlay. Is there a setting somewhere to stop the SceneKit part from sleeping?
Background:
I use SCNView.overlaySKScene. I have a indefinitely repeating animation of one of the subnodes of that overlay. As soon as an action and/or animation goes on in the SceneKit scene, the overlay 2D stuff also animates, but stops as soon as the 3D animations stop.
iOS 9.2.1.

A SceneKit view runs its update/render loop only when it knows there's animation going on. (Because if there's no change in what's to be rendered, rendering just wastes CPU/GPU time and eats up battery power.)
SceneKit is rather conservative in guessing when it should run the render loop. It runs if there are CAAnimations or SCNActions in the scene or if the physics engine is doing something, but I think that's about it.
If you've got other stuff that wants to run the render loop (like an overlay SKScene that needs to run its own game loop), just set the view's playing property to true.

Related

SceneKit drops to 30FPS when not moving

I have an scene with a few nodes. When there is some animation then it works with 60FPS. But when objects are not moving, it's dropping to 30FPS. I'm rotating camera using coremotion, so this is visible. Is there anything I can do to stop this behavior and keep 60FPS?
If you want to force a continuous refresh of the SCNView:
view.playing=YES
view.loops=YES

Draw circle and drag touch around SKSpriteNode

I am making a Sprite Kit game where the player (basically a stickman) has a running animation and a parallax scrolling background.
Now I have enemies that come near my player. To destroy these enemies sometimes I have to touch the enemies node to launch a rocket or attack them with an attack button or just jump over them.
Everything is working fine, but I want to add some extra moves to destroy them. I want some enemies that you can just destroy if you have drawn a whole circle around them. So imagine they come and you make a circle and then my player launch a laser or something. The problem is I have no idea where to start.
I haven't found anything on the internet. If it's too complicated or almost impossible how about touching my player node and dragging to the enemy?
EDIT: I think I have to create a custom GestureRecognizer that recognizes if a circle is drawn around a sprite and then runs the code. I don't know how this works ?
Yes, it's too complex. Not just from a coding point of view, but also from that of the player's experience.
Anything that requires complex gestures over a large amount of glass is annoying for the player because they're never going to have the same experience. Their finger's moisture and oil content always changes, as does the ambient temperature and cleanliness of their screen.
So big gestures required to be performed quickly (a gaming input like this) will sometimes be fun and smooth, and other times degrade as an experience based on the nature of the above properties.
Best to avoid them for a game's best possible experience.
If you must do it, there's two ways to research how.
Seek out "custom gesture" creation and utilisation through documentation and google, etc.
Think about using some kind of array to store all the points where the player's finger moves through during that circle gesture and attempt to discern if an enemy is within that space and then act accordingly.
--- probably other ways, too. But these jump to mind.

Lag using SKAction

I've finished my game which uses the method + (SKAction *)moveToY:(CGFloat)y duration:(NSTimeInterval)sec to move sprites and when they collide with another sprite they disappear but when one of them collides with another object and disappears the other sprites that are falling down make some lag and I don't know if I could use another method to move sprites without lag.
PS: The sprites move a little bit fast(from y:0to y:568 in 0.5 seconds), is that maybe the problem?

Why does SpriteKit physics performance seem to depend on what's rendered on the 1st frame?

This is something I've been struggling with for a while now, and I'm really hoping someone can shed some light on the issue. Basically, I have a scene with a bunch of colliding SKPhysicsBodies. If I put the camera in the middle of the action on the very first frame of animation, the entire simulation runs at about 17fps indefinitely. However, if on the very first frame of animation I start the camera off-screen such that nothing (or very little) is drawn that first frame, and then move the camera to the middle of the action on the 2nd frame, then the simulation runs at 60fps.
The simulation is exactly the same in both cases. Nothing is different other than what sprites are culled on the very first frame, yet that seems to make all the difference for the rest of the simulation's performance.
This has proven 100% reproducible in every case I come up with, so in order to make sure that my game runs at 60fps, I have to "prime" the camera by starting it way, way off-screen, render a frame, and then move the camera to where I really want it to be. If I don't do that, the game runs at a cripplingly low frame rate and will never speed up.

Synchronize UIView layout to OpenGL frames

We are developing a game that has 2d elements displayed with UIViews over an OpenGL ES view (specifically, we're using GLKit's GLKView) and are having problems keeping the positions perfectly in sync.
In the parent view's layoutSubviews, we're projecting 3d positions in the world onto the screen, and using those as locations for several UIView "markers" in the game. The whole game only updates in response to the user moving the camera, and the camera tells the view setNeedsLayout each time it moves.
Everthing's working fine, except that the markers seem to be roughly 1 frame out of sync with the 3d rendering. I say roughly because (1) it's an estimate! and (2) I'm wondering whether there's potentially a multithreading issue: doesn't GLKView sync to a special screen refresh callback or something?
Is there some way of hooking a view's layoutSubviews so that it sync's to the 3d view update?
Update: Weirdly, calling layoutIfNeeded immediately after setNeedsLayout makes the problem worse! Possibly 2 or more frames out. Really don't understand that!
What's triggering your call to LayoutSubviews?
It all depends where in the RunLoop your call is triggered vs. where your GLK update call is triggered.
In general, for what you're doing, I'd aim to do your layout as a side-effect of the GLK update - i.e. don't wait for layoutSubviews to change your position.
(if you're using OpenGL, then the whole "layout" system isn't much use to you: GLK is running in its own little world of variable frame rate, and you want to make that your reference point)
This is impossible to do correctly without drawing the frames of the video using OpenGL (drawing in the same context so that you are always sure that one frame contains the same time of video and animation). Everyting else you do, framerate compensation, lag prediction, only depends on chance, and will always be a little bit unsynchronized.
I'm not familiar with UIView but if there is any way to let it play audio and copy the frames to a texture, do that. The lag in the audio is much easier to compensate and much less noticeable by the humans than in the video.

Resources