SKSpriteNode centerRect behavior

Support for "9-slice" behavior in SKSpriteNode (using its centerRect property) is an excellent feature, as it's useful in quite many situations. However, I must say that the way it has been implemented is completely braindead.


Whose brilliant idea was it to tie the size of the sprite in this mode to the xScale and yScale properties? This makes it really difficult and awkward to use in many situations, and essentially impossible in others.


If you want to actually scale the resulting sprite smaller or larger (ie. everything, including the corner and the edges, get scaled), it's possible but really complicated and awkward. Essentially the roles of the 'size' and the 'scale' properties have been swapped. If you want to set the size of the 9-slice rectangle, you need to use the 'scale' properties, and if you want to set the scaling of the entire sprite, you need to use the 'size' property (making sure that the scaling of the sprite is 1 before you do that, or else you'll end up with the size being multiplied by the scale). This is completely backwards, and difficult to use.


It also interferes with everything that uses sprite scaling for whatever. If you have some function or class that takes sprites and performs all kinds of transformations to them, like scaling, if you give it a 9-slice sprite, it will not work properly, because now the scaling will actually modify the geometry of the slices rather than the scaling of the entire sprite.


This is perhaps most prominent if you want to use the basic trick for mirroring a sprite: Scaling by -1 on one axis. If you do that to a 9-slice sprite, it won't mirror it, but it will essentially glitch it. (The implementation of SKSpriteNode will draw some tiny part of the original sprite, extended over its current area, or something.) It's effectively impossible to mirror such a 9-slice sprite. This is highly annoying.


"No problem. Just use an SKNode instead, and put the 9-slice sprite as a child node of it." Except that SKNode does not support many things that SKSpriteNode does, such as size, anchorPoint and color, which are often essential when dealing with sprites. If you have a function that takes a SKSpriteNode as parameter, you can't give an SKNode to it.


How it should have been done is that the dimensions of the 9-slice sprite are defined with their own properties, rather than putting that completely unrelated functionality into the existing scaling properties.

Replies

This sort of problem comes from not designing (almost) anything about Sprite Kit. The entire framework is a blithe copy of what someone (with seemingly limited knowledge) knew of a few game engines. This particularly vexing mishmash of bad ideas looks to be copied from the NGUI "plugin" that became Unity's GUI system.


At the time NGUI was created, it was a half thought out effort to solve (what was considered to be) a soon to be officially fixed problem. The guy that made it didn't have much faith in it, and has said as much.


After years of muddling around and not releasing a GUI system, Unity bought this half baked "solution" and it became a "standard".


From the looks of the way Sprite Kit does 9 slice, someone simply copied how it might be done with GUI/NGUI of Unity, and stopped thinking at that point.


This also explains the Actions system, the texture packing and many other aspects of Sprite Kit...


The sad part is that there are some good things to copy from Unity, and those things weren't copied. The Entity/Component/Script system of Unity is (accidentally) quite good and easy to think in. The update loop also gets nowhere near the good parts of it.


And frameworks and game engines don't tend to get rebuilt right after they find the problems, so they double down... hence the "components" in GameplayKit. GameplayKit makes an effort to copy the ways of an ECS, but gets nowhere near close, and just adds more confusion, problems and complexity.

I totally agree. The fact that there is no documentation explaining this only makes me go mad every time I try to add such an image to my game.