How to create interactive grass

I’m currently building an open world game and I was wondering if anyone knows how to create interactive grass or a way to “paint” on grass to the terrain. I’ve videos showcasing this such as this and I was wondering if anyone knows how to accomplish this in studio.
Thank you in advance!

21 Likes

“Interactive” grass has been created recently by someone. They posted a couple of threads on it asking for advice. As far as painting the terrain with grass, it can likely be done with a plugin.

Can you produce a link to these threads?

I can’t seem to find them again

Oh, okay. I gave my response while this thread was a part of the Building Support section, although it has been since moved to Scripting Support which I don’t tend to read as I’m not a scripter. I hope somebody with more expertise can advise Lolaphobia, lol.

https://gyazo.com/dfa28f40f5be0551607ef924343d2579.gif by @EchoZenkai

7 Likes

Well this is in fact a scripting question. The main difficulty you will find in creating grass like this is optimization. What I describe below is by no means something that takes performance into account, rather this is just an idea of the process.

First things first you have to create the grass. This is really an artistic decision and doesn’t have much to do with the programming. For my sake I just used a bunch of slightly curved triangle beams (again, not really performance friendly)

RobloxStudioBeta_2019-02-25_20-39-32

Now moving onto the scripting. Every blade of grass has a base and a tip. The base won’t move because it’s stuck in the ground, but the tip will.

We compare the position of the player to the base of each blade of grass. If the base is within a certain bounding circle around the player then we’ll have to displace it. The general rule of thumb is that the closer the blade is to the center of the circle the further out we’ll displace it.

function grass:displace(pos, radius)
	local grass = self.grass;
	-- convert to object space since attachments are in object space
	local rpos = self.part.CFrame:pointToObjectSpace(pos) * Vector3.new(1, 0, 1) - UP*self.part.Size.y/2;
	
	for i = 1, #grass do
		local _, attach0, attach1, cfa, cfb = unpack(grass[i]);
		local v = rpos - attach0.Position;
		local t = 1 - math.min(1, v.magnitude/radius);
		attach1.CFrame = cfb - UP*t*radius - v.unit*t*radius;
		-- alternatively add some cos in there to animate the grass a bit
		-- attach1.CFrame = (cfb - UP*t*radius - v.unit*t*radius) + Vector3.new(math.cos(tick()), 0, 0);
	end
end

That’s the basic jist of it the result is the following:

Grass.rbxl (16.5 KB)

Again, you’ll want to make a ton of adjustments for performance reasons, but that’s a good starting block. Enjoy!

167 Likes

Very very nice! I assume you use this to get the grass, but how would you be able to split that up? image