SpriteKit Debugging Guide

Comtháng SpriteKit issues và general debugging tips for SpriteKit tiện ích pixshare.vns.


This document is a SpriteKit troubleshooting guide that supplements the SpriteKit framework references located within the Library. See the SpriteKit splash page for the complete suite of SpriteKit documentation. When troubleshooting an issue, start there first khổng lồ ensure you"re using the APIs properly.

This guide provides additional troubleshooting information that applies to SpriteKit as a whole và also covers individual problems that SpriteKit pixshare.vns have encountered in the Comtháng Issues and Debugging Tips sections.

Back lớn Top

Common Issues

The following are a danh sách of topics and issues SpriteKit game pixshare.vns frequently discuss along with known solutions. If a specific problem is not listed here, continue to the Debugging Tips section for general strategies khổng lồ troubleshoot SpriteKit issues.

Use SpriteKit objects within the ordained callbacks

SpriteKit is largely a single threaded game engine and as such the API provides pixshare.vns with callbacks lớn implement your custom game súc tích. The primary callbaông chồng for your game ngắn gọn xúc tích is update( _ : ). Other examples are didMoveToView() & didSimulatePhysics(). Modifying SpriteKit objects outside of the ordained callbacks (a background queue or anything else non-main-thread) can result in concurrency related problems. Even dispatching work on the main thread asynchronously or at a later time is risky because the closure is likely to lớn be done outside of the timeframe SpriteKit expects. If you"re experiencing a segmentation fault or other type of crash occurring deep within the SpriteKit framework, there"s a good chance your code is modifying a SpriteKit object outside of the normal callbacks.


Use DispatchQueue.async và asyncAfter to set flags and bởi vì not interact with SpriteKit objects (e.g., SKTexture, SKNode, SKShader, etc.). Chechồng flags within your scene"s update callbachồng to lớn operate on SpriteKit objects at that time.

Bạn đang xem: Debug events

How to animate the stroking of a path

SKShapeNode"s path can be animated by supplying a custom strokeShader that outputs based on a few SKShader properties, v_path_distance và u_path_length. Note that within the shader supplied below, u_current_percentage is added by us và refers to lớn the current point within the path we want stroked up to lớn. By that, the scene determines the pace of the animated stroking. Also note since strokeShader is a fragment shader, it outputs an RGB at every step which allows the stroke lớn be a gradient color if desired, which is demonstrated by the use of u_color_start and u_color_kết thúc.

The shader is defined in a text tệp tin named "gradientStroke.fsh" added khổng lồ the Xcode project:

void main()

if(u_path_length == 0.0)
// error as u_path_length should never be zero, draw magenta
gl_FragMàu sắc = vec4(1.0, 0.0, 1.0, 1.0);
else if(v_path_distance / u_path_length
float c = v_path_distance / u_path_length;
float v = 1.0 - c;
vec4 l = u_color_start;
vec4 r = u_color_end;
gl_Fragmàu sắc = vec4(clamp( l.r*v + r.r*c, 0.0, 1.0),
clamp(l.g*v + r.g*c, 0.0, 1.0),
clamp(l.b*v + r.b*c, 0.0, 1.0),
clamp(l.a*v + r.a*c, 0.0, 1.0));
gl_Fragmàu sắc = vec4(0.0, 0.0, 0.0, 0.0);

import SpriteKit

import GameplayKit
class GameScene: SKScene
var strokeShader: SKShader!
var strokeLengthUniform: SKUniform!
// define the start và kết thúc colors here
var startColorUniform = SKUniform(name: "u_color_start",
vectorFloat4: vector_float4(<1.0, 1.0, 0.0, 1.0>))
var endColorUnisize = SKUniform(name: "u_color_end",
vectorFloat4: vector_float4(<1.0, 0.0, 0.0, 1.0>))
var _strokeLengthFloat: Float = 0.0
var strokeLengthKey: String!
var strokeLengthFloat: Float
return _strokeLengthFloat
_strokeLengthFloat = newStrokeLengthFloat
strokeLengthUniform.floatValue = newStrokeLengthFloat
override func didMove(to lớn view: SKView)
// percentage is the only variable uniform since start and over color don"t change
strokeLengthUnisize = SKUniform(name: "u_current_percentage", float: 0.0)
// pass all uniforms khổng lồ the shader
strokeShader = SKShader(fileNamed: "gradientStroke.fsh")
strokeShader.uniforms =
strokeLengthFloat = 0.0
let cameraNode = SKCameraNode() = cameraNode
let path = CGMutablePath()
path.addRoundedRect(in: CGRect(x: 0, y: 0, width: 200, height: 150),
cornerWidth: 35,
cornerHeight: 35,
transform: CGAffineTransform.identity)
let shapeNode = SKShapeNode(path: path)
shapeNode.lineWidth = 17.0
shapeNode.strokeShader = strokeShader
// center camera over the rounded rectangle
let rect = shapeNode.calculateAccumulatedFrame()
cameraNode.position = CGPoint(x: rect.kích thước.width/2.0, y: rect.form size.height/2.0)
override func update(_ currentTime: TimeInterval)
// The amount incremented determines the pace of the animation.

Xem thêm: Tăng Cường Quản Lý Hướng Dẫn Viên Du Lịch, Quản Lý Hướng Dẫn Viên Du Lịch

strokeLengthFloat += 0.01
if strokeLengthFloat > 1.0
strokeLengthFloat = 0.0

Figure 1The animating path.

Zooming nodes about an arbitrary screen point

Zooming a node on a particular screen point can be challenging in SpriteKit. An intuitive thought is to lớn use anchorPoint and scale to lớn bởi so, however, a few caveats make it challenging:

Changing a node"s scale does not change its kích cỡ (therefore, nor does it change its underlying coordinate system). That can be an unintuitive sầu fact and it complicates point conversion by requiring you to lớn factor out the scale yourself.

Not every SKNode derivative sầu has an anchorPoint on which scale sizes about, and for those that bởi vì, adjusting the anchorPoint changes its visual location in the scene. This can be an unintuitive fact and it complicates the use of anchorPoint for zooming because it requires the unintended translation to lớn be undone.

A simple alternative approach is khổng lồ use position và kích thước instead. The following code snippets demonstrate zooming in và out around the mouse pointer.

Figure 2 - zooming nodes with the above code using mouse location as the anchor point.


SKShader limitations

The following are known limitations of SKShader in addition khổng lồ debugging tips.

Limitations of SKShader

GL extension checking within shader code supplied to lớn SKShader is not supported.

Debugging Tips

The following menu of topics are helpful in troubleshooting general SpriteKit development issues.

Choosing the renderer

Originally, SpriteKit was implemented in OpenGL & then moved lớn Metal in iOS 9 & OS X 10.11. It"s important to lớn be mindful of this for debugging purposes because some issues exhibit in one renderer but not the other. If you"re experiencing what you believe lớn be a SpriteKit bug, switch the renderer & kiểm tra for different results. While one renderer might offer a temporary workaround, you must file a bug report for renderer differences so the real underlying issue can be assessed for a fix.

Debugging SpriteKit memory problems

Problems with ever-increasing memory are not isolated lớn SpriteKit games but this section speaks khổng lồ a few instances that commonly arise.

Tab-based SpriteKit apps & SKScene caching

Apps that show SpriteKit scenes in a tab format can fill up memory quickly if prior scenes are not released while changing from one tab lớn another. For more imformation, see QA1889 - Tab-based SpriteKit Apps & Scene Caching.

General memory problems

The following danh mục are general techniques khổng lồ troubleshoot memory issues và their example use with SpriteKit games.

Debugging SpriteKit performance issues

This section covers tips lớn debug performance issues in SpriteKit games.

Use Time Profiler khổng lồ traông chồng down gameplay hiccups

Enable shader compilation failure logging

If an SKShader is not working and you"re unsure why, check for compilation errors in Xcode"s console. chú ý that error handling is encapsulated when using SKShader"s convenience initializer init( fileNamed: ) (see the signature comments in SKShader.h). To enable compilation failure logging, use SKShader( source:, uniforms: ) instead. Here"s an example:

func shaderWithFileNamed( _ filename: String?,

fileExtension: String?,
uniforms: ? = nil) -> SKShader?
let path = Bundle.main.path( forResource: filename, ofType: fileExtension )
guard let source = try? NSString(contentsOfFile: path!, encoding: String.Encoding.utf8.rawValue) else
return nil
let shader: SKShader
if let uniforms = uniforms
shader = SKShader( source: source as String, uniforms: uniforms)
shader = SKShader( source: source as String)
return shader

Create a focused sample

Often times when troubleshooting a SpriteKit issue, isolating the problem in a new smaller Xcode project can lead to a resolution. That"s because isolating the problematic behavior with minimal code distills the issue khổng lồ the handful of APIs that could be responsible. Another benefit is that alternative sầu options become more clear which can increase the chances of finding a workaround. Remember khổng lồ tệp tin a bug using the online Bug Reporter for any issues that you think might be a bug in an framework.

New document that covers comtháng issues encountered when developing SpriteKit games & general tips specific khổng lồ debugging SpriteKit apps.