How to create interactive grass

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