Adding collision to meshes placed with the (somewhat) new Foliage Mode is currently impossible, although we may want to enable collision if we use the Foliage system to add large objects like trees and rocks to our level (or even other things, creativity is your limit...). Adding such objects individually as normal static meshes not only is a pain, but poor for performance (you'll get thousands of draw calls, one for each tree, rock, etc.). A search through the forum returned no solutions, so I implemented my own and thought I'd share it.
This tutorial will show how to create collision for objects placed using the foliage system. You'll need basic understanding of unrealscript.
So, let's start with the basic. After you paint some foliage into your level, Unreal will group some of those trees and rocks and grass into one single mesh, containing several instances of the object you painted. This is done to decrease the number of draw calls, greatly improving render time when you have thousands of meshes (which is the case of foliage).
The class InstancedFoliageActor, instanced once in each level, contains a pointer to each of these large clusters of meshes through its variable InstancedStaticMeshComponents (an array<InstancedStaticMeshComponent>). So first thing we need is to get access to this class and iterate through these components. Put this in your GameInfo class.
(MyGameInfo.uc)
If you try this on a level with a lot of foliage used, you should get a lot of messages on your log.
Now, if you take a look at InstancedStaticMeshComponent.uc, you will see it has a very useful attribute: PerInstanceSMData. This object contains information of every mesh instance in this foliage cluster. Its type is InstancedStaticMeshInstanceData, which is a struct that contains, among other things, a transform matrix (var Matrix Transform). It also extends StaticMeshComponent, meaning you have access to which static mesh this cluster represents (var() const StaticMesh StaticMesh).
So let's decompose that transform matrix to get each instance's location, rotation and scale. UDK has built-in functions to decompose location and rotation only, not scale, so we'll have to implement that as well.
(MyGameInfo.uc)
If you run the game now, you should see a lot of red boxes around your foliage instances.
Now, we have the mesh, the location, scale and rotation. We just need to add collision to that. The logical choice would be a BlockingVolume, but volumes can't be spawned in run time (actually they can, but you can't change their shape or position, far as I know). What about an invisible static mesh actor? Sounds great, but instead of using, say, DynamicSMActor_Spawnable, let's create our own class, optimized for this purpose.
(BlockingMesh.uc)
Now we just need to spawn this class, using the variables we got earlier. Add this after the matrix decomposition.
Here we spawned a BlockingMesh, setting its owner to the level's InstancedFoliageActor (just for organization), and setting its location and rotation from the values we got earlier. Then we set the BlockingMesh's static mesh to that of the cluster's static mesh. Unreal will automatically assign the collision model, so don't worry about that. Finally, we set the scale.
One last thing: some meshes don't have a collision model. They typically include small objects like grass and flowers and shouldn't have collision. So, before spawning the blocking mesh, check if they have a collision model:
Run the game now, load a level full of foliage, and type in the console: show collision or show zeroextent. You should have collision on every foliage instance now. Hurray!

Performance
It is speculated that Epic didn't enable collision on foliage due to performance reasons, and indeed, adding collision to every foliage instance can be quite heavy. In my test map, which contains 9042 instances (7 different meshes), I got 40 FPS with collision (20ms on the game thread), and 55 FPS without collision (6ms on the game thread), so this is certainly pretty cpu intensive. Also, that's on a Core i7, so the performance impact should be even greater on weaker processors.
We probably don't need to check foliage collision everywhere, there are probably several forests on our map that are just eyecandy and the player can't reach them. So instead of creating collision meshes everywhere, let's create a new volume type, which tells "only create collision for foliage objects if they are inside me".
So delete everything we did so far on MyGameInfo.uc and create a new file:
(FoliageCollisionVolume.uc)
Compile this and open the editor. Create a builder cube that includes several of your level's foliage instances and right-click the Add Volume button. Choose FoliageCollisionVolume to create our custom volume.

When you run the game, collision should be created only for foliage inside that volume.


And that's it! I hope you found this tutorial useful.
This tutorial will show how to create collision for objects placed using the foliage system. You'll need basic understanding of unrealscript.
So, let's start with the basic. After you paint some foliage into your level, Unreal will group some of those trees and rocks and grass into one single mesh, containing several instances of the object you painted. This is done to decrease the number of draw calls, greatly improving render time when you have thousands of meshes (which is the case of foliage).
The class InstancedFoliageActor, instanced once in each level, contains a pointer to each of these large clusters of meshes through its variable InstancedStaticMeshComponents (an array<InstancedStaticMeshComponent>). So first thing we need is to get access to this class and iterate through these components. Put this in your GameInfo class.
(MyGameInfo.uc)
PHP Code:
event PostBeginPlay()
{
super.PostBeginPlay();
CreateFoliageCollision();
}
function CreateFoliageCollision()
{
local InstancedFoliageActor ac;
local InstancedStaticMeshComponent comp;
local int i;
//look for the InstancedFoliageActor
foreach AllActors(class'InstancedFoliageActor',ac)
{
//iterate through the various foliage components
for(i=0; i<ac.InstancedStaticMeshComponents.Length; i++)
{
comp = ac.InstancedStaticMeshComponents[i];
`log(comp);
}
}
}
Now, if you take a look at InstancedStaticMeshComponent.uc, you will see it has a very useful attribute: PerInstanceSMData. This object contains information of every mesh instance in this foliage cluster. Its type is InstancedStaticMeshInstanceData, which is a struct that contains, among other things, a transform matrix (var Matrix Transform). It also extends StaticMeshComponent, meaning you have access to which static mesh this cluster represents (var() const StaticMesh StaticMesh).
So let's decompose that transform matrix to get each instance's location, rotation and scale. UDK has built-in functions to decompose location and rotation only, not scale, so we'll have to implement that as well.
(MyGameInfo.uc)
PHP Code:
static final function vector MatrixGetScale(Matrix TM)
{
local Vector s;
s.x = sqrt(TM.XPlane.X**2 + TM.XPlane.Y**2 + TM.XPlane.Z**2);
s.y = sqrt(TM.YPlane.X**2 + TM.YPlane.Y**2 + TM.YPlane.Z**2);
s.z = sqrt(TM.ZPlane.X**2 + TM.ZPlane.Y**2 + TM.ZPlane.Z**2);
return s;
}
function CreateFoliageCollision()
{
local InstancedFoliageActor ac;
local InstancedStaticMeshComponent comp;
local vector loc, scale;
local Rotator rot;
local int i, j;
//look for the InstancedFoliageActor
foreach AllActors(class'InstancedFoliageActor',ac)
{
//iterate through the various foliage components
for(i=0; i<ac.InstancedStaticMeshComponents.Length; i++)
{
comp = ac.InstancedStaticMeshComponents[i];
//iterate through the various meshes in this component
for (j=0; j<comp.PerInstanceSMData.Length; j++)
{
//decompose the instance's transform matrix
loc = MatrixGetOrigin(comp.PerInstanceSMData[j].Transform);
rot = MatrixGetRotator(comp.PerInstanceSMData[j].Transform);
scale = MatrixGetScale(comp.PerInstanceSMData[j].Transform);
DrawDebugBox(loc,vect(200,200,200),255,0,0,true);
}
}
}
}
Now, we have the mesh, the location, scale and rotation. We just need to add collision to that. The logical choice would be a BlockingVolume, but volumes can't be spawned in run time (actually they can, but you can't change their shape or position, far as I know). What about an invisible static mesh actor? Sounds great, but instead of using, say, DynamicSMActor_Spawnable, let's create our own class, optimized for this purpose.
(BlockingMesh.uc)
PHP Code:
class BlockingMesh extends DynamicSMActor_Spawnable;
defaultproperties
{
Begin Object Name=StaticMeshComponent0
HiddenGame = true //we don't wanna draw this, it's just used to test collision
BlockRigidBody=true //DynamicSMActors have collision disabled by default
End object
bCollideActors=true //same here
bTickIsDisabled = true //greatly improves performance on the game thread
}
PHP Code:
CreatedBlockingMesh = Spawn(class'BlockingMesh',ac,,loc,rot);
CreatedBlockingMesh.StaticMeshComponent.SetStaticMesh(comp.StaticMesh);
CreatedBlockingMesh.SetDrawScale3D(scale);
One last thing: some meshes don't have a collision model. They typically include small objects like grass and flowers and shouldn't have collision. So, before spawning the blocking mesh, check if they have a collision model:
PHP Code:
if (comp.StaticMesh.BodySetup != none)
{
CreatedBlockingMesh = Spawn(class'BlockingMesh',ac,,loc,rot);
CreatedBlockingMesh.StaticMeshComponent.SetStaticMesh(comp.StaticMesh);
CreatedBlockingMesh.SetDrawScale3D(scale);
}

Performance
It is speculated that Epic didn't enable collision on foliage due to performance reasons, and indeed, adding collision to every foliage instance can be quite heavy. In my test map, which contains 9042 instances (7 different meshes), I got 40 FPS with collision (20ms on the game thread), and 55 FPS without collision (6ms on the game thread), so this is certainly pretty cpu intensive. Also, that's on a Core i7, so the performance impact should be even greater on weaker processors.
We probably don't need to check foliage collision everywhere, there are probably several forests on our map that are just eyecandy and the player can't reach them. So instead of creating collision meshes everywhere, let's create a new volume type, which tells "only create collision for foliage objects if they are inside me".
So delete everything we did so far on MyGameInfo.uc and create a new file:
(FoliageCollisionVolume.uc)
PHP Code:
/** Creates collision for foliage instances inside the volume */
class FoliageCollisionVolume extends Volume
placeable;
static final function vector MatrixGetScale(Matrix TM)
{
local Vector s;
s.x = sqrt(TM.XPlane.X**2 + TM.XPlane.Y**2 + TM.XPlane.Z**2);
s.y = sqrt(TM.YPlane.X**2 + TM.YPlane.Y**2 + TM.YPlane.Z**2);
s.z = sqrt(TM.ZPlane.X**2 + TM.ZPlane.Y**2 + TM.ZPlane.Z**2);
return s;
}
function PostBeginPlay()
{
local InstancedFoliageActor ac;
local InstancedStaticMeshComponent comp;
local vector loc, scale;
local Rotator rot;
local BlockingMesh CreatedBlockingMesh;
local int i, j;
super.PostBeginPlay();
//look for the InstancedFoliageActor
foreach AllActors(class'InstancedFoliageActor',ac)
{
//iterate through the various foliage components
for(i=0; i<ac.InstancedStaticMeshComponents.Length; i++)
{
comp = ac.InstancedStaticMeshComponents[i];
if (comp.StaticMesh.BodySetup != none)
{
//iterate through the various meshes in this component, if it has a collision model
for (j=0; j<comp.PerInstanceSMData.Length; j++)
{
//decompose the instance's transform matrix
loc = MatrixGetOrigin(comp.PerInstanceSMData[j].Transform);
if (ContainsPoint(loc)) //check if this instance is within the volume
{
rot = MatrixGetRotator(comp.PerInstanceSMData[j].Transform);
scale = MatrixGetScale(comp.PerInstanceSMData[j].Transform);
CreatedBlockingMesh = Spawn(class'BlockingMesh',ac,,loc,rot);
CreatedBlockingMesh.StaticMeshComponent.SetStaticMesh(comp.StaticMesh);
CreatedBlockingMesh.SetDrawScale3D(scale);
}
}
}
}
}
}

When you run the game, collision should be created only for foliage inside that volume.


And that's it! I hope you found this tutorial useful.
Comment