Considering the age of this thread, this reply is more for anyone else who stumbles onto this from a search engine… I spent a few hours today trying to figure out just how to accomplish this and managed to get it working in a fairly efficient way I think. So the first thing you need to do is make sure that your foliage has collision on the trace channels. Inside the foliage painter, you can set the collision type to block all and then custom. Then check ignore for everything but the two trace channels:
Under the photos I added a permanent link to them on my website in case they ever vanish from here.
Next, you want to create a custom Physical Material by opening your Project Settings, opening the Physics settings from the link on the left side, and then scrolling down until you get to the Physical Surface section. Under Surface 1 I just gave it the name “Bush” and then create a new Physical Material (Right click in content browser and go to Phyics - Physical Material) called Bush_PhysMat and setting the Physical Material type for your foliage materials to use your new Bush_PhysMat:
Then inside your player character BP, create a Set Timer by Function Name node and give it a function name like ScanForBushes. In my case it’s called UpdatePlayerPosition because I’m also using the player location to bend the foliage through a material using World Position Offset (I may post a tutorial on how to set this up later). From that custom event I trigger a “CheckForBushSound” custom event (though if you want you could just run that code from the first event):
The reason I use a Timer instead of Event Tick is because it’s slightly more efficient and the timing won’t change if your FPS spikes or drops.
It’s inside this “CheckForBushSound” custom event where the magic happens:
(The link has a higher res image for easier readability)
All you need to do is create a MultiSphereTraceByChannel (it’s vital to be multi so you can action on every foliage instance immediately) and for each Hit Component, you want to Cast to FoliageInstancedStaticMeshComponent, get the Material, get the PhysicalMaterial and then check to see if it’s equal to your custom Physical material. I also use an AND boolean operation to check to make sure the player is actually moving to prevent the sound effect from spamming if a player stands inside a bush. From there, you simply play your Foliage sound effect at the location of the player through a Do Once that resets after the sound finishes playing (plus a little padding time).
And that’s a rather simple way to implement your Foliage sounds. The nice thing with this system is you can use multiple custom Physical Surfaces/Physical Materials to check for other foliage types like grass, or branches or what have you, and play a different sound for each type, all within the same function.