1
\$\begingroup\$

I am building a sprite that I want to spin along an axis. I am using SpriteKit on iOS for this, but I'm sure that the question is not really tool specific.

In my case, I have a sprite such as:

unrotated sprite

and I want to rotate it around the red line as if it is a spinning disc spinning in 3D (even though it is only a 2D sprite).

SpriteKit gives me the SKTransformNode class that allows me to adjust the X, Y and Z rotation of the node. So I am able to rotate the sprite along the X or Y axis in pseudo 3D. The following 3 images attempt to give you an idea of what I'm trying to achieve:

first rotation second rotation third rotation

I thought I should be able to animate the rotation around the X and Y axis in a way to achieve this but I've found it harder than expected.

I'm hoping that someone can point me in the right direction.

[edit]

to further illustrate what I don't want, here is what happens using simply Y scaling without using an SKTransformNode. Note that the image inside the circle does not reflect as it turns.

Not working

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

Try creating the art so that the red line is horizontal, then rotate it in Swift on its zRotation, and animate scaling along the scaleX or scaleY to achieve the effect.

For example:

class GameScene: SKScene {
    private var sprite : SKSpriteNode?
    override func didMove(to view: SKView) {
        self.sprite = self.childNode(withName: "//axis") as? SKSpriteNode
        if let sprite = self.sprite {
            sprite.zRotation = -CGFloat.pi / 3
            let scaleDown = SKAction.scaleY(to: -1.0, duration: 2)
            let scaleUp = SKAction.scaleY(to: 1.0, duration: 2)
            let sequence = SKAction.sequence([scaleDown, scaleUp])
            sprite.run(SKAction.repeatForever(sequence))
        }
    }
}

Spin

\$\endgroup\$
10
  • \$\begingroup\$ Thanks for this suggestion. This is close to what I've done already but have been unable to get the effect I wanted. I'll have a look at this again now. \$\endgroup\$
    – PKCLsoft
    Commented Nov 9, 2023 at 10:09
  • \$\begingroup\$ @PKCLsoft Can you elaborate? What I posted (and tried) appears to be what you described. You can make it look even more real by adding some easing to what I posted so that the scaling is not linear in speed. \$\endgroup\$ Commented Nov 10, 2023 at 17:40
  • \$\begingroup\$ NOTE: If the red line is horizontal as a starting position, this will work easily. Maybe later today I can post a gif or movie. \$\endgroup\$ Commented Nov 10, 2023 at 17:59
  • \$\begingroup\$ I have perhaps not provided a good example for the image as it appears almost as if there is a mirror image on either side of the line. Within my actual art assets this will not be the case, so this trick, whilst effective, will not really spin the internal image as such. What I could do I guess is that as the yScale hits zero, spin the internal image (in this case, the asterisk) 180 degrees. That might actually work quite well. Sorry for not being responsive; I'm stuck in another issue atm. \$\endgroup\$
    – PKCLsoft
    Commented Nov 16, 2023 at 22:40
  • 1
    \$\begingroup\$ PS: Adding a little easing will make the effect even more real. \$\endgroup\$ Commented Nov 19, 2023 at 22:39
3
\$\begingroup\$

I think this would be easiest using SKTransformNode.setQuaternion instead.

This makes it easy to express a rotation by some angle around any axis you choose, rather than only rotations around the coordinate axes as with Euler angles. You can come up with Euler triples to correspond to any arbitrary orientation, but it's complicated for diagonal axes.

Instead, you can init a simd_quatf using a given angle (expressed as a Float in radians) and axis (SIMD3<Float>) to rotate around. Pass that to setQuaternion and you're set. You can repeat this each frame, incrementing your angle argument over time to make it spin, while holding the rotation axis fixed.

This way, you don't have to do any trigonometric calculations yourself — that's all handled by the init function.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for this. I'd given up on getting a solution to this. I'll try this out! \$\endgroup\$
    – PKCLsoft
    Commented Nov 9, 2023 at 10:08
  • \$\begingroup\$ I've ended up accepting Johns answer as it provides a much simpler solution to the problem and also means I no longer need to use SKTransformNode (which I think will be a performance gain). \$\endgroup\$
    – PKCLsoft
    Commented Nov 19, 2023 at 22:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .