Siriss
Siriss

Reputation: 3767

SpriteKit - SKCameraNode constraints leave space at top and bottom

I am using the DemoBots example provided by Apple to work with my first SKCameraNode. I have the constraints working in the X axes, but not the Y. I get gaps at the top, even though I constrain it to the Max and Min height.

Also, my camera is constrained to 0.0 on my Dog character, but it does not move to keep the Dog in the center of the camera as the Dog moves around the world.

Here is my camera constraints function. Do I also need to do something in update?

//MARK: Camera
    /// Constrains the camera to follow the Dog without approaching the scene edges.
    func setCameraConstraints() {
        // Don't try to set up camera constraints if we don't yet have a camera.
        guard let camera = camera else { return }

    // Constrain the camera to stay a constant distance of 0 points from the player node.
    let zeroRange = SKRange(constantValue: 0.0)
    let dogLocationConstraint = SKConstraint.distance(zeroRange, toNode: self.dog)

    // Set dog constraints to worldNode bounds.....
    let catConstraints = SKConstraint.distance(SKRange(lowerLimit: 0.0, upperLimit: self.size.height), toNode: self.worldNode)
    self.dog.constraints = [catConstraints]

    let scaledSize = CGSize(width: size.width * camera.xScale, height: size.height * camera.yScale)

    let worldContentRect = self.worldNode.calculateAccumulatedFrame()

    let xInset = min((scaledSize.width / 2), worldContentRect.width / 2)
    let yInset = min((scaledSize.height / 2), worldContentRect.height / 2)

    // Use these insets to create a smaller inset rectangle within which the camera must stay.
    let insetContentRect = worldContentRect.insetBy(dx: xInset, dy: yInset)

    // Define an `SKRange` for each of the x and y axes to stay within the inset rectangle.
    let xRange = SKRange(lowerLimit: xInset, upperLimit:xInset)
    let yRange = SKRange(lowerLimit: 0, upperLimit: insetContentRect.maxY)

    // Constrain the camera within the inset rectangle.
    let levelEdgeConstraint = SKConstraint.positionX(xRange, y: yRange)
    levelEdgeConstraint.referenceNode = self.worldNode

    camera.constraints = [dogLocationConstraint, levelEdgeConstraint]
   }

Here are some pictures of the gaps on top and bottom.

Top

bottom

What can I do to fix this?

(I can't show my character due to NDA).

Upvotes: 2

Views: 1124

Answers (1)

netskink
netskink

Reputation: 4539

Here is how I learned to do it:

//
// Create our camera
//
SKNode *avatar = [self childNodeWithName:@"avatar"];
SKCameraNode *camera = (SKCameraNode *) [self childNodeWithName:@"camera"];

id horizConstraint = [SKConstraint distance:[SKRange rangeWithUpperLimit:100]
                                     toNode:avatar];
id vertConstraint = [SKConstraint distance:[SKRange rangeWithUpperLimit:50]
                                    toNode:avatar];

id leftConstraint = [SKConstraint positionX:[SKRange rangeWithLowerLimit:camera.position.x]];
id bottomConstraint = [SKConstraint positionY:[SKRange rangeWithLowerLimit:camera.position.y]];
id rightConstraint =

    [SKConstraint positionX:[SKRange rangeWithUpperLimit: (backgroundboundary.frame.size.width - camera.position.x)]];
id topConstraint =
    [SKConstraint positionY:[SKRange rangeWithUpperLimit: (backgroundboundary.frame.size.height - camera.position.y)]];

If your off using this technique as I was, examine your camera position in the gamescene. The unmovable crosshair is the zero,zero point of the coordinate system. Make sure your background and camera are positioned relative to that.

Upvotes: 1

Related Questions