2D Toolkit Forum
2D Toolkit => Support => Topic started by: coolTool on August 21, 2012, 10:25:43 pm
-
how to flip bone animation (and save 1 drawcall) without localScale.x = -1;
animation as spider in the demo scene. :)
-
Use the sprite.scale property instead.
-
This is a good question, and sprite.flip will not flip the hierarchy beneath. The best option is to simply use normal scale on the root object - as they are all scaled uniformly, all children should batch automatically (can't say for certain with Unity's batching rules, but you should get full or close to full batching).
I've been prototyping a DynamicSpriteBatcher for this very purpose and while it works, a lot needs to be done to get it working fully in all cases. This should really help - but I can't commit to anything until 1.8 is out and in the wild.
-
sorry, if i don't understand (my bad English :'( ), but if i scale root gameobject (2 same gameobject are present in scene), drawcall has increased.
-
If one is the child of the other, scaling the parent object shouldn't affect draw calls.
-
:-[
-
That is not the sprite scale.
You're using the Transform.Scale, when you should be using the sprite.scale, look at attached picture
-
if I use sprite.scale:
-
my bicycle 8)
-
Ok so in this case, flipping player1 will increase draw calls by one (as player2 won't be batched with player1). While there are ways around this, is it really critical in this case?
Workarounds -
1. Manually flip using sprite.scale, hierarchically. What needs to happen here is you start with the base object, sprite.scale *= (-1,1,1), and for each child, the sprite.scale *= (-1,1,1) and also transform.localPosition *= (-1, 1,1). This should be the easiest to do in your case.
2. Use the dynamic sprite batcher (yeah I know, I've not released it to public yet, still some issues to resolve, but works nicely)
-
I think I know what coolTool is talking about because I think I'm having the same issue. I don't think it's specific to 2DTK but maybe you can offer some advice either way. I've got a hierarchy of tk2dSprites that represent a character similar to the scary looking spider in one of the examples. I animate the character in Unity by rotating the individual sprites (the legs, arm, hands, etc). This works great until I want to flip the character on the x-axis, for example, to make the character run the opposite direction on screen. The easiest way to do this, as you said, is to just scale the parent GameObject by -1 on the x-axis. And as you said this will result in an additional draw call, which isn't too big of a deal at least in my case. The real problem is that if you try to rotate a child object that has a parent with a non-uniform scale (like -1, 1, 1), then the rotations break. For example the feet will appear to detach from the legs, which will appear to detach from the body.
I tired to fix this by abandoning the notion of scaling the entire character via the parent GameObject, and instead used the Scale property on the tk2dSprite component. I flipped the x scale (FlipX()) for each individual sprite of the character, and then transformed the position of each sprite across the local origin of the character. I ended up with a character that looked just like it'd been scaled at the parent when not being animated. However when animated it was clear that the animations themselves still behaved like the character was facing in the original direction (duh, I guess I should have expected this). This can't be fixed by just playing the animation backwards.
Any bright ideas? Thanks for the help.
-
I think I figured this out. The solution for me was to use rotation instead of scale to make the character (just a hierarchy of sprites) appear to face the opposite direction. I rotated the parent 180 degrees about the Y-axis so the camera sees the back of the sprites. Since the scale of the parent remains uniform, this doesn't trigger any of the aforementioned problems. I did have to re-position the individual sprites on the z-axis to make sure that the sprites layered as expected (the eye balls remained in front of the head and not covered up behind), but this was as easy as just negating the z component of each sprite's local position.
-
This will be a whole lot easier once I release the dynamic sprite batcher. I'll try to get this out there at least in beta form after 1.8 is out.
-
Sorry for digging up an old topic, but I'm running into the same issue.
tommyv's solution seems good, but I'm using animations on my characters. The animations all store the z position of the sprites so if I flip and inverse the z positions in the hierarchy, the animations set it back.
Is there a way to prevent animations from setting the z position? Setting the position on the sprites every frame to order them seems awfully expensive (I have about 100 active characters at once, built from 16 sprites each). Or maybe some other way? :-[ I've been puzzling with this for a long time and everything I try fails for another reason.
-
Why don't you just delete the scale key on the animation?
-
The problem isn't the scale key, but the position keys, when the sprites move. It keeps resetting the z position to "pre-flip".
-
I think I understand, but I'm not sure if there is a clear cut solution to this. You might have to write a manager script to modify z based on flipped state.
-
I don't have a problem writing (complex) code, once I know a working solution. Right now I'm trying to find anything that will work without killing performance.
Basically what happens is this:
- Character turns around >> I flip z order of children (once)
- Character gets animated (by mecanim) >> the animation restores the pre-flip z order
Right now the only way to avoid that would be to reorder the sprites on LateUpdate, after the animation happened. But I can imagine reordering 1000s of sprites every frame is not going to be good for performance.
How would you solve this (with a manager or without)?
This seems like a common problem to me, when using animated characters that are built from sprites. How is this usually done?
-
If you're already animating the character and mecanim is already setting the z values, I can't see what harm another pass of changing the z values is going to do. How much of a hit this is going to be depends on how your hierarchy is set up. If its largely flat with a few nested children it'll cost a lot less to update than a very deeply nested hierarchy where all children. Alternatively if you are on Unity 4.3, use the order in layer property instead of z to sort your sprites.
Since you already have code to flip the z, try calling it every frame and see how much of a hit it is and if it is a problem to start with?
I don't know if there is a way to get mecanim not to stomp your z values - that would probably be one for the unity answers forum.
-
You are right. It's worth a shot. Although my code for flipping just negates the z position, so calling it repeatedly will mess things up. But I'm sure I can create some sort of simple system that just keeps setting every transform to the correct z value.