Unreal is really friggin' stupid sometimes (or: how I solved a problem with cloth)

What follows is a story about the ridiculous steps I went through in order to get a character’s cape to collide with the ground. If you’re here because you have that problem too and you don’t feel like reading my diary, feel free to skip to the punchline.

A Statement of the Problem

Like most people, I have characters in my game. Most of these characters have cloth simulation. And, like most characters in most games, they sometimes fall down. They get knocked down, they die, whatever. There are situations where they are lying on the floor underneath them for some time. The problem is, their cloth does not lie down with them. Their cloth happily collides with their body, and it looks great. But the floor might as well not even be there. Capes and ropes and baggy jackets drape from their necks like hangars, straight down into the void below the floor.

“This must have an easy problem to fix”, I reasoned. “Surely, no actual person making a video game would be satisfied with a clothing simulation that broke the instant the character fell down. Characters fall down all the time! Why, I can hardly think of a game where no character is ever seen lying on the floor.” It seemed perfectly sane to assume that this problem would have been encountered thousands of times in various peoples’ development cycles and that the forums would abound with obvious solutions.

Collide With Environment

Now, a cursory google search of this issue returns a forum post by Epic Staff detailing how, in Unreal 5, the new Chaos Cloth system provides a simple way to produce environmental collision. Naturally, this is where I began my journey.

I followed the steps, as outlined, but the result was… not what was shown in the forum post

Cloth just slides right on through the floor. I double-checked my configuration. Triple-checked it. Quadruple-checked it. It was correct, EXACTLY as specified. “Collide With Environment” was checked, “Force Update” was checked; what was wrong?

I spent hours fiddling with this. Eventually, I decided to go back to the source and try to reproduce the steps of the tutorial more precisely… specifically, I created the engine default cylinder shape as the collider test. And hot dang, it worked exactly!

What gives? Well, if you look closely, you’ll see that the cape collides with the cylinder, but still doesn’t collide with the floor. This is the clue. Doing a bit of thorough testing and using collision visualization, I was able to figure out what’s wrong:

Cloth environment collision does not respect Complex Collision As Simple.

That’s it. That’s all it was. My floor sheet in testing is based on a smooth rolling ramp component that can’t be approximated with convex primitives so I was using complex collision, and it looks like cloth doesn’t respect that. But I’m very annoyed, because I spent hours debugging this, and it could have been solved with a single line in the documentation. Why isn’t this extremely important limitation noted anywhere? I can understand the limitation for practical reasons; cloth collision is computationally expensive and relies on certain tricks under the hood. It’s perhaps a frustrating limitation, but it’s a reasonable one… but for the love of God, why didn’t anyone write this limitation down?

Personal Floors and Attachment Collision

Well, I’m a resourceful guy. I’m not gonna let collision complexity rules slow me down. I had a different idea: what if each character has a “cloth box”, a sort of “personal floor” that follows them around wherever they go? We can use a line trace to project this component onto the floor beneath them when they’re in the air, rotate it to the surface normal of the trace collision with the ground, and (barring certain weird edge cases on sharp surfaces) the character can always have a flat box just under their feet to catch cloth. Even if the floor itself doesn’t have simple collision, this box will have simple collision, so the whole thing should work just fine.

You’d like to think that, I know. But the results…

Still nothing. I checked, double-checked, and triple-checked that the “Collide with Attached Children” setting was correct. I checked, double-checked, and triple-checked that the collision floor had the correct response channel. More hours and hours of debugging, trying to solve this problem, when experimentation hit on something strange.

If I had a test mesh set to Collide With Environment, it would respect the cloth floor of a character in the scene.

This cemented it: the floor collision was fine. In a fit of desperation, I tried setting the character’s clothing to Collide With Environment and… it worked. It worked perfectly.

Collide With Attached Children didn’t seem to do anything, but attached children can be treated as part of the Environment for collision purposes. Once again, I couldn’t begin to tell you what’s going on here, because the documentation doesn’t explain it. Clearly, the cloth can collide with these boxes, but it won’t treat them as attachments. It has to “think” they’re the environment to pay attention to them, even when they’re the direct children of the cloth simulation.

It’s stupid but, hey. Success!

Portable Floors Are Still Just Floors

So at this point, I’m feeling okay. Playtesting reveals some obvious problems, though; namely, that as these characters move around, their cloth floor is getting in the way. They can bump the player with it, they push physics objects around with it, it’s still just a floor. But, collision is like that. There are ways around it.

What I do is, I go configure a new Collision Response Channel in my project settings. I call this ClothCollide, and its only job will be to collide with cloth. That way, it can act as a cloth floor, but it won’t bump stuff. I set the Personal Floor asset to this channel, configure the correct collision response, and…

It breaks. Again.

I test for more hours and hours. At this point I’m close to throwing my computer out the window. I go back to the working setup and start systematically changing things one by one until I isolate the problem. And yes, I isolate it.

Environment cloth collision will ONLY respond to the WorldStatic Channel.

Do I mean it only responds to objects with mobility set to Static? No. I mean that specific collision channel, WorldStatic, no matter the object properties, is the only one that world cloth collision checks against. It’s just hard-coded in there, unchangeable even from a project settings menu. And once again, this isn’t ANYWHERE in the documentation. This limit is just presumed, it’s a magic-number-enum, and nobody says anything about it in any tooltips, engine docs, tutorials, etc. It doesn’t come up in testing, presumably, because when you create environment objects, they default to this collision channel. But how could anyone, in the course of actually making a game, not run into this? This specific collision channel is a hard-coded requirement of cloth collision; not a property of the collision mesh, just the named enum Epic happened to designate by default for static objects?

The Punchline

In the end, I was able to make this work. You can too. The key takeaways are:
-Cloth environment collision does not respect Complex Collision As Simple
-Collide With Attached Children didn’t seem to do anything, but attached children can be treated as part of the Environment for collision purposes
-Environment cloth collision will ONLY respond to the WorldStatic Channel

If you need a character cloth component to always collide with the floor, even when that floor has Complex Collision, which I stress again is something basically everyone will need at some point or another, you can set up a line trace that moves a simple collider box to the floor, rotated to its surface normal, and configure this in the character with cloth. Tick the trace and update every frame, and make sure that the box is WorldStatic and that the character mesh’s cloth is set to Collide With Environment (and Force Update)

But what frustrates me is the fact that I spent 8-10 hours with my head in my hands, staring at the screen, completely unaware of what the $%&! was going on! Why? Because I was basically reverse-engineering the Cloth Collision set-up for Chaos via trial and error to find all the hidden assumptions, magic variables, and specific use-case restrictions that nobody has documented anywhere. None of this is exposed, and none of it is written down, and we all just have to guess.

That’s ridiculous.

Look, I sometimes use Unreal to do things that the developers didn’t intend, and I know that. I take it to weird places and have to hack stuff together, because what the engine is actually capable of isn’t always what it was intended to do. But this isn’t one of those times. This is one of the most basic use-cases for cloth that I can think of. The steps I had to go through are annoying, and they represent a frustrating limitation on Chaos; one that seems like it’s carried over from the NVCloth limitations. But really, my issue isn’t that I have to attach a box with a specific collision channel to a character to create a fake floor so their cloth always collides with it. My issue is that it would have taken me 10 minutes to set that up if the restrictions on Cloth Collision were documented properly. That’s time I’ll never get back.

Anyway. If you’re having a hard time with environmental cloth collision being finicky (and Google tells me many of you are) I hope this post solves your problem.

6 Likes

A quick addendum, since I didn’t make it clear:

The object you want to collide with cloth only has to be on the channel WorldStatic, it doesn’t have to behave like a WorldStatic object in any other way. I set the ClothFloor to collide with nothing except the enemy character mesh’s collision channel, so it stopped acting like a floor. Then I put a tag on the Cloth Floor that identifies it as such, so that cases where I traced against the WorldStatic channel specifically to do things, I could check the component for that tag and ignore it if the Cloth Floor was found. It’s hacky, and probably not best practice for collision usage, but it DOES work.

Thank you for enduring such nonsense for our benefit.
The lack of documentation is astounding.

This Comment was written for a previous version of Unreal Engine and has not been updated for the current Unreal Engine 5.1 release.

Where may I subscribe to future Diary Entries ?

We also had to find out about all these, on our own.

It’s a good way of resolving the issue, using Line Trace to detect the Floor.

For our purpose we’ll need the Complex Collision to simply work, as that’s the only way of having an accurate Cloth Simulation for the whole Character, is not just about a Cape or a Jacket.

Seems that we’ll have to find the solution on our own, but would be great if the Engine supports that, by default.

Cloth Simulation Discussion - Development / Programming & Scripting - Epic Developer Community Forums (unrealengine.com)

I’m actually still stuck. Cannot get cloth to collide with the world to save my life. It collides with the character. Objects in the world are set to world static. Checkboxes as per the docs. No world collision.

Also having this issue in 5.0.3 and cant get it to work