Download

Possible to clear a section of foliage during gameplay?

My game is largely a building game, and i’d like to avoid having foliage poking through player bases.

If there anyway to remove foliage in real-time during gameplay?

You can have foliage disappear through distance based culling if I recall correctly.

Thanks for the response. But distance based culling won’t allow me to despawn foliage in a just a specific spot (or will it)?

I’m not sure if you can specify specifics areas as opposed to distance from the camera.

I think if you want to use actual foliage, placed with the foliage tool, then you would need to put the foliage into microlevels that you would unload when you clear the foliage.

Or instead… now I’m thinking of some crazy solutions. They may or may not work, but they’re all definitely crazy.

You might be able to do something fancy with a shader and RotateAboutAxis. Make some way for the shader to see if its area has been cleared, and if so, flip the foliage upside down or something like that.

Actually, this might involve Flash. Make a Flash movie that’s 4096x4096. Make each pixel an object that you can turn black or white. Give it a function that will take in X,Y coordinates and then set the pixel to black or white. (Maybe there’s already an Actionscript function that lets you do this?) Render that movie to a texture. Use that texture inside your foliage material.

Or wait, no, can’t you do this with a canvas? Yeah, make an UnrealScript canvas that’s 4096x4096. Draw 4096x4096 1x1 black and white squares on it. Drop that into your foliage material, scale it appropriately by multiplying a 2D vector and adding it to a TexureCoordinate. Then flip the foliage upside down if its XY world coordinates are in a black square.

If you are using the foliage tool, try to do a bucle in the InstancedFoliageActor and perhaps you can hide each item or changing its scale. Check the InstancedStaticMeshComponents array. I didn’ tried, I don’t know if they can be hidden or deleted.

Using levels you need to include the base in the level, if not you can’t place foliage. Landscape can be splited in stream levels, each one with their own instancedfoliageactor, but that is not useful in this case.

Yes, you can hide individual meshes in the foliageactor:



exec function HideFoliage(bool B)
{
    local InstancedFoliageActor F;
    local int i;

    foreach AllActors(class'InstancedFoliageActor',F)
    {
        for(i=0; i < F.InstancedStaticMeshComponents.Length; i++)
        {
	        F.InstancedStaticMeshComponents*.sethidden(B);
        }
    }
}  


I’m going to look how disable collisions too.



exec function HideFoliage(bool B, int R)
{
    local InstancedFoliageActor F;
    local int i, n;
    local vector PL;
    local InstancedStaticMeshComponent IC;
	
    PL = getalocalplayercontroller().pawn.location;

    foreach AllActors(class'InstancedFoliageActor',F)
    {
        for(i=0; i < F.InstancedStaticMeshComponents.Length; i++)
        {
	    IC = F.InstancedStaticMeshComponents*;
	    for(n=0; n < IC.PerInstanceSMData.length; n++)
	    {
		if ( vsize(PL - MatrixGetOrigin(IC.PerInstanceSMData[n].Transform)) < R)
		{
		    IC.sethidden(B);
		}
            }
        }
    }
}


This hide/unhide the meshes using a radius from the player location. But I can’t find how to disable collisions. I have tried with SetCollisionType, but seems that not working with instancedmeshes.

Also this hides the complete cluster, not a unique mesh. But perhaps is useful for you.

Awesome, thanks for your insight guys. @Cobalt I’m going to have a play around with your solution now. Cheers

Hmmmm unfortunately this crashes the app for me (runaway loop detected). I have more than 1000000 foliage instances on my map.

Umm… I was testing with 34000 instances in about 4000 clusters.

Are you using the foliage tool for grass too? In my tests that was very very slow… I had to use a foliage script instead.

Yes I’m using the foliage tool for grass. I have 18000 clusters and am seeing pretty good performance after a lot of tweaking. Here’s my game btw: http://store.steampowered.com/app/418030/Subsistence/

So you use a script to spawn/despawn your grass as your player moves around?

Yes, I use a script for that, for grass and trees. The problem is that the instance placement is random, I have tried a way to get a unique number based on position to avoid random numbers, but not working well yet.

Then instead of looping through AllActors (which you should only do very rarely, and when it’s your only option), iterate through TouchingActors, and only clear the InstancedFoliageActors that are touching the building that you’ve placed.

I have a good news, I have improved the foliage tool with a function, without changing the number of clusters or max draw distance.

Before:

foliagetest1.jpg

After:

foliagetest2.jpg

That’s quite an improvement. I’d like to know what you did to get that improvement, but maybe you should post that info in a new thread so we don’t derail the discussion on how to hide foliage.

Doesn’t touch require that the actors have collision? That would be fantastic if that works though.

I’ve tested TouchingActors() and VisibleActors(), and neither ever return foliage instances :frowning:

Darn. That would’ve been convenient. How about CollidingActors? OverlappingActors? Any other options? UDK | UnrealScriptIterators

It’s possible to turn on collision for foliage, right? If you give your grass mesh a really short collision box (by saving the .fbx file with an additional box mesh named UCX_[name of your mesh]) then your player should be able to walk over it without noticing, but it should still show up on a collision check, so long as your building’s collision reaches down to the ground.

I can hide/unhide clusters, but I don’t know yet how disable collisions. I have tried the usual methods for staticmesh and don’t work with instances. Also I’m not sure about to disable collisions for a unique instance, instead for the entire cluster. I have to see the source files.