Is there a way to visually see sprite kit's SKPhysicsbody borderline?
Asked Answered
C

8

31

I am using bodyWithPolygonFromPath to define the volume of a physics body, and I used http://dazchong.com/spritekit/ to get the paths required. But the path does not seem correct and I wish to see the borderline of the physics body path to see if the shape is correct.

Is there any way to see the physics body's borderline?

I tried the following code, but it doesn't work.

ship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];

CGFloat offsetX = ship.frame.size.width * ship.anchorPoint.x;
CGFloat offsetY = ship.frame.size.height * ship.anchorPoint.y;

CGMutablePathRef path = CGPathCreateMutable();

CGPathMoveToPoint(path, NULL, 50 - offsetX, 110 - offsetY);
CGPathAddLineToPoint(path, NULL, 18 - offsetX, 16 - offsetY);
CGPathAddLineToPoint(path, NULL, 140 - offsetX, 15 - offsetY);

CGPathCloseSubpath(path);

SKShapeNode *yourline = [SKShapeNode node];
yourline.name = @"yourline";
yourline.path = path;
[yourline setStrokeColor:[UIColor redColor]];
[self addChild:yourline];

ship.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
ship.zRotation = - M_PI / 2;
Cartridge answered 19/1, 2014 at 6:5 Comment(0)
H
70

For Objective-C & iOS < 7.1

In your ViewController.m find this code

SKView *skView = (SKView *)self.view;
skView.showsFPS = YES;
skView.showsNodeCount = YES;

After the last line add

skView.showsPhysics = YES;

Build and Run and you should see all the physics Body borderline

i noticed that you add the shapeNode to self instead of the spriteNode so try the following

SKSpriteNode *ship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
CGFloat offsetX = ship.frame.size.width * ship.anchorPoint.x;
CGFloat offsetY = ship.frame.size.height * ship.anchorPoint.y;

CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 50 - offsetX, 110 - offsetY);
CGPathAddLineToPoint(path, NULL, 18 - offsetX, 16 - offsetY);
CGPathAddLineToPoint(path, NULL, 140 - offsetX, 15 - offsetY);
CGPathCloseSubpath(path);

ship.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];

[self addChild:ship];

SKShapeNode *shape = [SKShapeNode node];
shape.path = path;
shape.strokeColor = [SKColor colorWithRed:1.0 green:0 blue:0 alpha:0.5];
shape.lineWidth = 1.0;
[ship addChild:shape];

For Swift & iOS >= 8.0

let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
skView.showsPhysics = true

And if you want a custom borderline

let ship = SKSpriteNode(imageNamed: "Spaceship")
let offsetX = ship.frame.size.width * ship.anchorPoint.x
let offsetY = ship.frame.size.height * ship.anchorPoint.y

let path = CGPathCreateMutable()
CGPathMoveToPoint(path, nil, 50 - offsetX, 110 - offsetY)
CGPathAddLineToPoint(path, nil, 18 - offsetX, 16 - offsetY)
CGPathAddLineToPoint(path, nil, 140 - offsetX, 15 - offsetY)
CGPathCloseSubpath(path)

ship.physicsBody = SKPhysicsBody(polygonFromPath: path)
addChild(ship)

let shape = SKShapeNode()
shape.path = path
shape.strokeColor = SKColor(red: 1.0, green: 0, blue: 0, alpha: 0.5)
shape.lineWidth = 1.0
addChild(shape)

Already tested :]

Good Luck!!

Heimlich answered 22/1, 2014 at 22:25 Comment(2)
Where are you seeing 'skView.showsPhysics'? Maybe you are referencing a beta update?Treva
yeap that only works in iOS 7.1 Beta, my answer is updated thanksHeimlich
J
5

Swift

In GameViewController.swift, add this line:

override func viewDidLoad() {
    ...
    if let view = self.view as? SKView {
        ...
        view.showsPhysics = true // <--- add this line
    }
}
Juratory answered 1/11, 2018 at 0:48 Comment(0)
F
2

SpriteKit provides a built-in feature that draws light-blue borders around all of your physics bodies.

Example sprites with physics body borders shown

SwiftUI

Include the showsPhysics debug option when you instantiate your SpriteView:

var body: some View {
    let scene = SKScene(fileNamed: "MyScene")!
    SpriteView(scene: scene, debugOptions: [.showsPhysics])  // <-- HERE
}

Here's the documentation for all the debug options, which also include useful features like showsFPS and showsNodeCount.

Cocoa/UIKit (Swift)

In your view controller's viewDidLoad, enable the showsPhysics property of your SKView:

override func viewDidLoad() {
    super.viewDidLoad()
    let skView = self.view as! SKView
    skView.showsPhysics = true         // <-- HERE
}

Cocoa/UIKit (Objective-C)

In your view controller's viewDidLoad, enable the showsPhysics property of your SKView:

- (void)viewDidLoad {
    [super viewDidLoad];
    SKView *skView = (SKView*)self.view;
    skView.showsPhysics = YES;            // <-- HERE
}
Fylfot answered 28/5, 2022 at 13:48 Comment(0)
T
1

For testing purposes, I would setup the ship as an SKShapeNode, comment out yourline SKShapeNode for now and set the ship.path to the same path you are using for your SKPhysicsBody.

Or you could use this:

https://github.com/ymc-thzi/physicsDebugger

Treva answered 19/1, 2014 at 8:36 Comment(0)
B
1

In the new 7.1 beta there is functionality to allow this as stated above.

Beerbohm answered 23/1, 2014 at 11:32 Comment(0)
L
1

I know this is a bit late, but I thought you might be interested in my new tool which automatically creates a path around the sprite image (so you don't have to manually click on the points yourself), and then you can adjust various settings to better suit your requirements. The tool also outputs both Objective C and Swift program code for adding the path to a sprite physics body. Hope it's helpful to some people. Thanks:

http://www.radicalphase.com/pathgen/

Lohman answered 26/4, 2015 at 19:18 Comment(2)
sorry the domain name expired - tool is back online again now though :)Lohman
New Update: Now includes a force convex mode (enabled by default) to ensure 100% compatibility with SpriteKit Physics Bodies, and also to reduce the points count - enjoy! :)Lohman
P
0

Your shape node code is correct. It looks like yourline may be added to the scene before the actual ship, so the ship sprite will be drawn on top of it, making it obscured. Make sure you set yourline.zPosition to the topmost value, or ensure [self addChild:yourline] is executed after [self addChild:ship].

Pollitt answered 22/1, 2014 at 12:48 Comment(0)
G
0

This will add a red line shape on top of your node. Use same path as you defined for the physics body of your node.

+(void)debugPath:(CGPathRef)path onNode:(SKNode*)node {
    SKShapeNode *yourline = [SKShapeNode node];
    yourline.name = @"yourline";
    yourline.path = path;
    [yourline setStrokeColor:[UIColor redColor]];
    [node addChild:yourline];
}

I.e. usage:

[[self class] debugPath:ship.physicsBody.path onNode:ship];
Grabowski answered 16/2, 2014 at 1:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.