Unreal Marketplace Version Out of Date
The current version of the RMC on the marketplace is quite old. This will be updated shortly as v4 is stabilized!
The current version of the RMC on the marketplace is quite old. This will be updated shortly as v4 is stabilized!
You will need to start with a code project. This does mean you’ll need all the build dependencies necessary to create c++ projects in Unreal. However this doesn’t mean you’ll need to use C++ at all, just that the engine needs to be able to build the plugin. To turn a blueprint project into a code project, you can go to “Add New C++ Class” in the editor and it should set everything up for you!
You can download the RMC from one of the links above.
Navigate to your project folder, and assuming the folder doesn’t already exist, create a ‘Plugins’ folder in the root of your project.
Within the plugins folder create a folder called RuntimeMeshComponent and copy the contents of the version you downloaded into this folder, making sure not to nest subfolders, all the files/folders in the directory of the .uplugin file should be in your newly created /Plugins/RuntimeMeshComponent folder.
At this point you should be able to relaunch the project and the editor should detect the new plugin and compile it for you!
You should be able to start using the RMC!
To make the RMC available in your C++ project, you must first install it from either the marketplace or GitHub as described above.
Next, in your projects build file ‘YourProjectName.Build.cs’ you must add this line:
Now you should be able to #include the headers like any other plugin and use the RMC from C++!
Using it from Blueprint isn’t recommended as creating meshes relies on lots of small operations, and BP has fixed time cost per operation. This means that, when using it from BP, generating meshes will often hang the engine. We recommend making the provider in C++, then giving it the data it needs through BP if you really want to, so that all of the generation can be both multithreaded and done in C++, while keeping the data logic in BP.
To install, do just like the previous section.
Meshes are represented through a vertex buffer and index buffer. These work in tandem to represent a mesh. The vertex buffer contains a list of all the unique vertices in the mesh, including their position, normal, tangent, color and texture coordinates. The index buffer, in the case of the RMC is in the form of a triangle list. This is laid out as a contiguous list of indices into the vertex buffer 3 at a time representing the 3 points of a triangle.
The vertex buffer is a list of vertices with all its corresponding data for all the unique vertices in the mesh. There are several options, which can affect the memory consumption, rendering performance, and visual quality of the mesh.
The elements of the vertex buffer are:
Depending on the configuration above, the total vertex size can range from 28 bytes for a normal precision tangents, normal precision texcoord single channel, to as much as 96 bytes for all high precision components with 8 texture coordinate channels.
The index buffer is meant to map the vertices into triangles. Within the RMC this takes the form of a triangle list, so indices will be in groups of 3 one after the other to define the 3 points of each triangle, each group of 3 is separate from the others and has no dependence on the others. With that said though order of the vertices within the triangle does matter for culling (See Winding Order below), and order of triangles within the buffer can have performance effects through things like cache coherency, locality, transform cache, and overdraw.
The index buffer can be either a 16 bit integer, or 32 bit integer per element, so it will consume 2 to 4 bytes per element. 16 bit integer is the default as it can handle meshes of up to 2^16 or 65,536 vertices.
Winding order refers to the order the vertices are reference for the triangle, this is important as one of the most common ways of improving performance is through backface culling. This works by looking at the direction the triangle wraps to detect if it’s a front or backface, and if it is found to be a backface then the triangle will get culled in hardware. By default Unreal Engine uses ClockWise Culling, so you should make the order of the vertices when referenced in the index list wrap Counter-ClockWise when viewed from the visible side.
It is possible to disable backface culling in Unreal by using two sided materials. If your mesh appears to render inside out, then you need to reverse the winding order.
Each RuntimeMeshComponent can have 1-8 Levels of Detail or LODs, each of which can have any number of sections. Each LOD is separate from the others, and so can have different numbers of sections and different materials bound to those sections.
Each LOD has a ScreenSize associated to it. This is the percent of the screen the bounding volume has to cover before this LOD is rendered.
Unlike the ProceduralMeshComponent and old RMC, materials are handled similarly to how StaticMesh handles them. URuntimeMesh holds a number of material slots, setup by SetupMaterialSlot, each has a index, name, and material. You can find these slots by index or name. Each mesh section can be assigned to any slot.
The RuntimeMeshComponent, like the StaticMeshComponent, has override materials (which was how RMC and PMC previously handled materials). These materials override the slots by index, and allow different components to bind different materials even when they share the same underlying mesh data.
Collision in the RMC has a few different parts, including basic settings and two collision types each of which has its own benefits and limitations.
Simple collision is made up of Boxes, Spheres, Cylinders, and Convex Elements. These are the basis of simple collision, which is required for movable objects that can interact with the environment and perform overlap tests. These are all convex shapes, as concave collision detection is far more complex. You can have none, one, or multiple of each of these 4 shapes, but you must have at least one to have any form of simple collision/physics simulation. Convex means that any line between two points belonging in the volume belongs to the volume.
Convex Elements are a convex mesh object. These can be generated directly by you, or possibly through a process known as convex decomposition where you take a source mesh and generate one or more convex shapes to represent it. This is how UE4 handles arbitrary shapes for collision. Convex elements are slower to compute than other primitives, and are limited to 256 vertices.
Note : Collisions don’t have to be perfect, since the primitives are invisible. Sacrificing accuracy for performance is alright : Avoid using convexes.
Complex collision is made from a triangular mesh. This can be either from your renderable mesh data, or a custom simplified mesh for collision. Usually the latter is better for collision performance, but takes extra effort to generate. No two complex collision shapes can perform collision tests, so complex collision only objects are not allowed to simulate physics. Having a line trace set to complex will return the complex collision mesh’s triangle index on hit.
The collision settings object is used to set the simple collision shapes, as well as some basic collision cooking settings.
Collision Cooking is required for convex elements and complex mesh. This process builds internal structures for performing high performance collision, but it takes a non-trivial amount of time to perform this collision on complex meshes. With this the RMC supports Async Cooking which can be turned on or off through the flag bUseAsyncCooking.
Complex as simple collision is where you have no simple collision for a shape and let the complex collision be used for things such as line tracing which would normally use the simple collision. This setting is controlled by bUseComplexAsSimple on the collision settings object.
CookingMode can be set to either CollisionPerformance or CookingPerformance. The first prioritizes efficient collision detection at the cost of a little more effort in cooking to build optimal collision structures. The second prioritizes quickly cooking meshes over having optimal collision structures.
The Runtime Mesh Component is made up of several distinct parts, each of which provides a portion of the overal system. Together the combination can be very extensible, or very simple. If you’re familiar with how UStaticMesh and UStaticMeshComponent works, this will be very similar with a couple extra pieces.
URuntimeMeshComponent is the main component that allows you to place a URuntimeMesh in the scene and interact with it exactly like UStaticMeshComponent. It’s possible to have multiple URuntimeMeshComponents all sharing a single URuntimeMesh, this means that a single copy of the gpu buffers can be shared among several individual components that all can act independently while drawing the same mesh. This is not the same as instancing which draws multiple copies of the mesh at different locations/rotations within the same component, but they all function together.
URuntimeMesh is the data carrier component. It is responsible for owning the GPU buffers, and the physics object that can then be used by one or more URuntimeMeshComponent’s. When you update the mesh data of a URuntimeMesh all the linked URuntimeMeshComponents will receive the mesh update together and they will all start rendering the new mesh. The URuntimeMesh DOES NOT store any mesh data in main memory, it simply copies it out to gpu memory (VRAM) and then destroys its cpu side copy. For collision it will pass the data to PhysX/Chaos and once the cooked collision shapes are created then it also removes the copy of the raw mesh data for collision as it’s no longer necessary. It relies on the URuntimeMeshProvider to get any of this data again if it needs it.
URuntimeMeshProvider is the base class for the provider system. The provider system is how a URuntimeMesh gets the configuration, renderable mesh data, and collision settings/data. URuntimeMeshProviders’ are composable so they can be chained together. For example if you create your own provider that only generates the renderable data, then you can use URuntimeMeshProviderCollision with it to generate the collision data from your rendering data. A URuntimeMesh must have a valid URuntimeMeshProvider to function, but that provider can be either a single provider or a chain of providers. This will in the future also allow the RMC to decide when to generate additional LODs instead of having to create them all upfront as you do now.
URuntimeMeshProviderPassthrough is a base class for pass through providers. These work by linking one or more providers to them and doing internal logic on the returned results from the linked providers before passing the result on to the URuntimeMesh.
URuntimeMeshModifier is the base class for the modifier systems. Some providers support applying generic modifiers to them that can modify the mesh data as it passes through the provider. These are allowed to do things such as clean mesh data, or generate the extra index buffers, but they’re not allowed to generate mesh data directly, that is up to the provider. These are simply for common functionality that you’d rather not implement yourself. There is a URuntimeMeshProviderModifiers that can be placed between your provider and the URuntimeMesh to apply these, and the URuntimeMeshProviderStatic has a built in modifier support.