0

I am building a game using Spritekit and am trying to build a raycast that will connect the player with the point where the player tapped. It will be like a rope that connects the player to the point where he or she tapped. For example if a player taps at the point x: 0, y: 0 then it will become a rope that connects both things with each other. With the time the rope will become shorter and the player will be dragged against it. The player does have a physicsbody. When the player releases the finger the rope will be remove and the player are not going to be dragged to that point anymore.

I want to archive the same thing as if you search raycast in unity but with spritekit.

I know how to implement the touch function as well as when he or she releases a touch. So the question is how do I make a raycast as described. I would also like to have some sort of visual effect which means a skshapenode or something that indicates where the player is going.

Have tried using SkPhysicsJoints but I'm not successful.

Any help would be appreciated!

Edwin123
  • 19
  • 2
  • Why do you need a ray cast? Sounds like a simple line segment to me – Knight0fDragon Feb 10 '20 at 01:44
  • The point is that the player will be connect by a rope to where he or she taps. For every one second or so the rope will become shorter and the player will be dragged with physics against that point. If you are able to do that with line segment than it's absolutly okey. Could you possible show code about how to implement it? Thanks! – Edwin123 Feb 10 '20 at 18:16
  • Huh? That is not a ray cast nor a line segment. You need to rework this question to better explain what you are trying to do. – Knight0fDragon Feb 10 '20 at 18:43
  • Have updated the question. Thanks for your effort! – Edwin123 Feb 10 '20 at 20:12

1 Answers1

0

Raycast is supported by physicsWorld object on your scene, with the method

func enumerateBodies(alongRayStart start: CGPoint, end: CGPoint, using block: @escaping (SKPhysicsBody, CGPoint, CGVector, UnsafeMutablePointer<ObjCBool>) -> Void)

You can use like this:

self.physicsWorld.enumerateBodies(alongRayStart: playerPosition, end: clickPosition) { body, point, vector, object in
    if let node = body.node as? SKSpriteNode {
        node.color = SKColor.red.withAlphaComponent(0.2)
        let pointNode = SKSpriteNode(color: .cyan, size: CGSize(width: 5, height: 5))
        pointNode.position = point
        let path = CGMutablePath()
        path.move(to: playerPosition)
        path.addLine(to: clickPosition)
        path.closeSubpath()
        let line = SKShapeNode(path: path)
        line.strokeColor = .green
        line.fillColor = .green
        self.addChild(line)
        self.addChild(pointNode)
    }
}

And get this result on each click:

enter image description here

The complete example it's here: https://github.com/Maetschl/SpriteKitExamples/blob/master/Raycast2dLinesVsObjects/Raycast2dLinesVsObjects/GameScene.swift

Maetschl
  • 1,330
  • 14
  • 23