Flipping a Character Composed of Several Meshes

I’m working on a 2D game and all of our characters are composed of about 5-10 meshes each (one for each arm, one for each leg, etc.). Our characters share the same set of materials, so no matter how many characters are on screen we get the same number of draw calls.

I’m looking for a way to flip a character so that it appears to be facing the opposite direction (for instance, a character might change directions when running).

This seems like a simple problem, but the only working solution I’ve found so far is to set a character’s scale to -1. This destroys our draw calls, though, because any kind of scaling breaks Unity’s batching system. This solution won’t work unless all characters decide to face the opposite direction at the same moment in time.

I’ve seen a few posts on Unity Answers that talk about reversing the triangles on the mesh, but this didn’t work for me for some reason (maybe because my characters are composed of several meshes? Or because they’re playing animations?).

Has anyone else found a way around this problem without having to create a second set of flipped textures and animations? :face_with_spiral_eyes:

Thanks for the help :slight_smile:

It sounds like you’re doing characters in a similar manner to what I’ve been doing except one key difference - instead of my characters being made of 5-10 discreet meshes that auto-batch, they’re each a single skinned mesh. The downside is that each character is a separate draw call. The upside is that they can be easily flipped by scaling them -1, and each individual body part can be freely scaled too without any adverse effects.

Hmm…we tried treating each character as a single mesh early on (by combining meshes in Maya), but our animations stopped working inside Unity (maybe that’s because we weren’t using bones?). So we ended up keeping the meshes separate simply because it didn’t break our animations :slight_smile: But we haven’t given much thought to the flipping issue until now… :frowning:

How is it that you can scale an individual body part without affecting draw calls? I’m assuming you’re using a single texture atlas for each character?

Well basically, scale isn’t a factor if you’re not relying on batching.

Basically I merge all my body parts in maya so it’s a single mesh with a single material/texture atlas, and therefore a single draw call. To be able to animate the different parts as if they were still separate, I build a simple skeleton and skin the various parts of the mesh to it.

Edit: A word of warning, this presents another problem which I forgot to mention initially - depth sorting. I assume your various parts are using alpha blending? The order you select them when you merge them in maya will ultimately decide which order they render in. Unlike batching, which automatically adjusts on the fly based on the distance of each element from the camera, you’re sorta committing your mesh to a specific rendering order once you merge it in Maya. If you need your character’s bits to be able to change their rendering order on the fly, you might want to figure out a different solution to your character flipping altogether.

Can’t you just rotate the character on one axis by 180 degrees?
And use a shader with cull off or so, to make the back faces visible.

@Mika, Yes, we’re using alpha blending on our characters’ body parts. We might have to take another look at combining the meshes if we can’t get this flipping issue sorted out. We’re just a bit intimidated by the skinning process in Maya :slight_smile: It’s a whole new world for us, and there doesn’t seem to be much documentation out there for our particular use cases.

And thanks for the heads up regarding rendering order. I don’t think we have any cases where we would need body parts to change their rendering order on the fly, but we’re only now realizing that flipping is a big issue, so we haven’t given much thought to that at all so far :face_with_spiral_eyes:

@marjan, We tweaked the Unlit/Transparent shader to make the back faces visible. But rotating our characters by 180 degrees looks pretty ugly :frowning: Any front facing features (eyeballs, front arm, front leg) aren’t visible at all from the back since our characters are simply a collection of flat planes layered on top of each other.

Couldn’t you just offset the eyes, arms and legs when flipped so you can see them or would you have other issues?

Maybe I could. But it seems like if I have an animation playing on my character Unity ignores any adjustments I’ve made to any one of the meshes.

For example, if there’s no animation playing I can just adjust the rotation and position of the plane with my characters’ eyes on it. But as soon as an animation starts playing, the rotation on the eyes reverts to whatever it was before :face_with_spiral_eyes:

Regarding performance options and low draw calls importance on iPhone I think only good way is making character as a single combined mesh. You just have to make distance between the planes in 3D software and keep order of planes from back to front before combining meshes. Also, few trials and errors with combining, exporting and importing will help solve problems.

I recently had a similar problem with our main character. My approach is to use culling so that I can flip the whole object. You then need to fix the z-index of the different parts. Since an animation can override this you will need to have a parent game object for each part. So the parent object gets animated and the child object can have it’s z-position changed during the flip. A hassle yes but it should work. I would create a character script that does the heavy lifting for you regarding the flipping and z-offsetting that you can then reuse.

Great insight, johot. I’ll give that a try today and see how it works.

We’re also making a bit of progress by combining all of our meshes into a single mesh and using bones for animation. By using a single mesh with culling turned on, we can simply rotate the character 180 degrees to view the backside. The problem we’re seeing with that is the pivot point for the characters seems to be in the middle of nowhere rather than the centre of their mesh. So rotating them 180 degrees places them off camera. Not sure why that is, but we’re still exploring…

I’d be happy to hear about your progress on creating meshes with bones. Are you using Maya? Blender? We are thinking of trying this approach also, right now we have animated using the built in tool with Unity. Not really the ultimate tool :stuck_out_tongue:

To make the flipping easier I made a method that takes an array of transforms and then moves them so that bodyPart.z = -bodyPart.z. Works great! But I had to make sure I used the correct coordinate system, so I had to use some InverseTransformPoint, and TransformPoint because of all the parenting. Can post the code if you need it.

I also needed to do some extra parenting, so now i have things like:

LeftLeg
->LeftLegSprite
->LeftFoot
→ LeftFootSprite

We’re using Maya, but the process should be similar with Blender. The guys who are making So Many Me are using Blender with success. Unity’s animation tool can be frustrating :slight_smile:

Do you mind posting a code snippet? That would be fantastic :slight_smile:

We’re working on posting a tutorial detailing our entire workflow once we figure all of these things out. Hopefully that will be useful to some people :slight_smile:

Ah a blog post would be great! Looking forward to that!

	private void AdjustBodyPartAfterFlip(Transform bodyPart)
	{
		// Get world position
		Vector3 currentPositionRelativeToBody = mainBodyObject.InverseTransformPoint(bodyPart.position);
		
		currentPositionRelativeToBody.z = -currentPositionRelativeToBody.z;
		
		// Calculate back to local space
		Vector3 newPosition = mainBodyObject.TransformPoint(currentPositionRelativeToBody);
		
		bodyPart.transform.position = newPosition;
	}

Run that on each body part. I created a Transform[ ] array where I can drag and drop all the body parts. And as I mentioned earlier, you must have a parent object for each body part, so each sprite must be on it’s own game object and not on the object of the parent (that gets animated).

Thanks for the code snippet, johot! That might come in handy, especially after some recent discoveries :frowning:

We were having an issue rotating our combined mesh 180 degrees. The problem was that the pivot point on the combined mesh in Unity wasn’t at the centre of the mesh…it was somewhere way off in the distance. This is strange to us because the pivot point is placed perfectly in the centre of the mesh when viewed in Maya. Something is getting lost in translation when importing our FBX into Unity…

To fix the pivot point in Unity we parented the combined mesh to an empty game object. But this was still giving us problems. It seems the only way to truly centre the pivot point is if the empty game object is in the exact same position (visible position – not the transform information) as the combined mesh before parenting. Very confusing…this took us a few hours to figure out :slight_smile:

But now that we have that sorted out we discovered a new problem – skinned meshes don’t dynamically batch!

This is terrible news for us :frowning: We can’t use only 1 material per character as MikaMobile suggested since we’re doing character customization. We need 1 material per set of body parts (e.g., 1 material for all the shirts in the game, 1 material for all of the hair, etc.). We might need to go back to our non-combined mesh characters and animate the free-floating planes rather than bones. If that’s the case, your script will come in handy :slight_smile:

Ugh, we solve one problem only to run into another… :slight_smile:

I tried your code out, johot, and that got us halfway there. The character flips perfectly, but the animations on each of the limbs no longer play. How did you author your animation? How do you avoid breaking it when you add the empty game objects as parents for each sprite?

Ah I see what has happened I think.

The Unity animation system is very fragile, if you rename a game object or move it in the hierarchy of your character all animations for that part is lost until you add a new object with the same name in the same location.

So say you had a body part called “leg”. You can’t create a new parent for this leg and call it “legParent”, you must keep that “leg” object and instead put a new child object in it called “legSprite” for example… if not all your animations for that “leg” are lost and must be remade.

Hope that works for you!

Ahh, I forgot that we’re authoring our animations differently. We’re doing it all in Maya, so the constraints may be different. I made sure to preserve all the names as you said, but that didn’t work :frowning:

We’ll do a bit of exploring in Maya and see if there’s something there we can change…

Thanks for your continued help, johot!

Aha you are using Maya already, I thought you where going to but hadn’t started yet, then im afraid im not much of help at this time :slight_smile:

Looking forward to that tutorial btw!

try with simple

transform.localScale.x =-1;

It works perfect for me