Here at Epic, we get one day a month nominated as ‘Epic Friday’, on which we can work on pretty much anything we like. A couple of months ago I worked on a really simple ‘cable component’ using rope physics for hanging up in levels, to add a bit of life. It’s an effect that has been seen in other games for years, but I wanted to see how easy it would be to add as a plugin to UE4! Here is what I ended up with:
To do the actual cable simulation, I used a technique I’ve played with a couple of times called ‘Verlet Integration’. It is very well known in game development; you can find all kinds of articles about it, the first one I remember is from Thomas Jakobsen (http://graphics.cs.cmu.edu/nsp/course/15-869/2006/papers/jakobsen.htm).
The idea is to represent the cable as a series of particles, with ‘distance constraints’ between them. The particles at the ends are ‘fixed’ and move with whatever they are attached to. The ones in the middle are ‘free’ and fall under gravity. Each step, you update the velocity and position of each particle, and then move them to satisfy the constraints. The ‘stiffness’ of the cable is controlled by the number of times we iterate to enforce the constraints, each step.
I won’t go into the maths here, but if you have the UE4 source code it’s only about 60 lines of code in the UCableComponent class, inside the functions VerletIntegrate and SolveDistanceConstraint.
Now that I had a nice chain of particles bouncing around, I needed to render it. This was a pretty good test case for creating a new type of geometry in UE4, and it turned out to be quite easy. I had to create a new FCableSceneProxy class, which is the renderer representation of the cable. Each frame I pass the new particle positions from the simulation (which is done on the main thread inside TickComponent) to this proxy, via the SendRenderDynamicData_Concurrent function. On the render thread I lock and update the index and vertex buffers to make a ‘tube’ mesh. For each vertex I need to calculate a position, a texture UV, and three tangent basis vectors. X points along the cable, Z points straight out from the cable (the normal), and Y is perpendicular to X and Z.
I expose properties on the component for number of sides, radius of the tube, as well as how many times to tile UVs along the cable.
Now that I could see the cable and play with it, I wanted to attach it to things. Unreal Engine 4 already allows any SceneComponent to be attached to any other, so I just added an option to attach the ‘end’ particle to a different component, with an offset. The final details for the cable look like this:
And that was it! You can try this out by adding a Cable Actor to your level (or a Cable Component to a Blueprint). It is certainly a fun addition to UE4, but there is a lot more that I would like to see added:
- Add collision with the world.
- Response to forces, explosions etc.
- Multithread the simulation instead of doing it on the main thread.
- Stop rebuilding the index buffer every frame as it doesn’t change.