How to make Interactive Grass?

while wait(tweentime * (tweenbackMultiplier/2)) do
	if wind then
        local CFrameDifference = CFrame.Angles(math.random(-windStrengh, windStrengh), math.rad(0), math.random(-windStrengh, windStrengh)
		for i, grass in ipairs(GrassFolder:GetChildren()) do
			local windtween = TS:Create(grass.PrimaryPart, tweenInfoWind, {CFrame = grass.PrimaryPart.CFrame * CFrameDifference)})
			windtween:Play()
			if not touching then
				wait(tweentime / 1.2)
				local normaltween2 = TS:Create(grass.PrimaryPart, tweenInfoWind, {CFrame = grass.RotateMain.CFrame * CFrame.Angles(math.rad(math.random(-1, 1)), math.rad(0), math.rad(math.random(-1, 1)))})
				normaltween2:Play()
			end
		end
	end
end

It probably occurs because you are multiplying the current CFrame by the new ‘CFrameDifference’ that i’ve put in, You will want to check that the ‘windtween’ is not called more than once, just make sure it’s not doing it over and over again (check your while wait(tweentime * (tweenbackMultiplier/2)) do)

Copy the code i sent as it is now because i’ve edited it a bit, Come back to me if it still doesn’t work

6 Likes

hey, TheHeroGamer001 I was looking at this topic and it seems very interesting. Is it possible if you could send a video of how it turned out, I want to try and implement this into my game but I don’t know how it turned out so I would like to see an example first!

how did you get the wind system to work I have been trying to figure it out but I am not able to. i have no idea how you implemented it into the script

As shown here, this is how I would get the wind to work. It has been 2 years and i haven’t been developing for awhile so I may not have the answer for you right away.

But the idea is that you have ‘wind gusts’ so at every time interval (tweentime * (tweenbackmultiplier/2)) it will apply a tween to each grasspart transforming it to move in the direction fo the wind.

Try using the quoted piece of code and if possible, DM me about this so we are not necrobumping this thread

3 Likes

I’ve had the same issue with grass and wanted to make one and I found that your solution is very helpful but I can’t seem to know where exactly to place everything or whether if the script is local or not.
image
image

And I also have this error in output

I know it’s been a couple months and I’m very sorry about that :sweat_smile:

definitely a localscript; you don’t want the server micro-managing rendering tasks

2 Likes

Wild West does NOT use the interactive grass, that Roblox provides.


(Yes the grass mesh is quite primitive)
This is all done in a local script to compensate for the servers processing
(Meaning this does not replicate but it is very efficient)

(Layout Of grass and folder)
image

(Video of grass working and wind)

(RBXM (ROBLOX MODEL FILE) FILE)
grasssys.rbxm (33.2 KB)

(How to use the file)

Hello!

Do you know if this system can be used for cars? Like it would do the same events as a player but with an object? Yk?

Hmm i dont get what you mean could you make the example more broader (Clearer) Please? :sob:

Yea mb

Like yk the same mechanics that work for the player when they walk on the grass? Could you do the same thing but with a car?

ok wait i am sorry for my late resposne i assume you mean with doors and yes it would work

Mb I was sleeping.

No, I mean like a car would drive over the grass and the grass would move like when the player walks over it.

Oh yeah that would work let me make a example rq

1 Like

Roblox isnt lettting me stuff this into a .rbxl file for some resaon but here is the code
remember you need to add two attributes in the script these are the two attributes the script assumes that the wheels are named “Wheel” And Make sure can touch is on for the wheel

(if you dont know how to set attributes through the properties tab here is a resource)
Properties Window | Documentation - Roblox Creator Hub.

(The attributes you need to set on the script)
image

(And the code)

local GrassFolder = workspace.Grass
local TS = game:GetService("TweenService")

-----||      Settings      ||-----
local multiplier = 28
local tweentime = .8
local cooldown_devision = 8
local tweenInfoNormal = TweenInfo.new(tweentime * 2, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
local tweenInfoTouched = TweenInfo.new(tweentime)
local RandomSize = false

-----| Debounce Dictionary |-----

local CoolDown = {}
for i, grass in ipairs(GrassFolder:GetChildren()) do

	grass.PrimaryPart.Transparency = 0
	grass.RotateMain.Transparency = 1
	if RandomSize then 	grass.PrimaryPart.Size = Vector3.new(math.random(2,8),grass.PrimaryPart.Size.Y,math.random(2,8)) end

	grass.HitBox.Touched:Connect(function(hit:BasePart)
		if hit.Parent:FindFirstChild("Humanoid") then
			CoolDown[grass] = true
			local hum = hit.Parent:FindFirstChild("Humanoid")
			local movedir = hum.MoveDirection.Unit

			if movedir.Magnitude > 0 then

				local facevector = grass.RotateMain.CFrame * CFrame.Angles(math.rad(movedir.X * multiplier), math.rad(0), math.rad(movedir.Z * multiplier))				
				local TweenMove = TS:Create(grass.PrimaryPart, tweenInfoTouched, {CFrame = facevector})

				TweenMove:Play()

				task.wait(tweentime / cooldown_devision)
				CoolDown[grass] = false
				return end

			CoolDown[grass] = false
		elseif hit.Name == "Wheel" then
			CoolDown[grass] = true
			local movedir = hit.AssemblyLinearVelocity
			if movedir.Magnitude > 0 then

				local facevector = grass.RotateMain.CFrame * CFrame.Angles(math.rad(movedir.X * multiplier), math.rad(0), math.rad(movedir.Z * multiplier))				
				local TweenMove = TS:Create(grass.PrimaryPart, tweenInfoTouched, {CFrame = facevector})

				TweenMove:Play()

				task.wait(tweentime / cooldown_devision)
				CoolDown[grass] = false
				return end

			CoolDown[grass] = false
			
		end
	end)

	grass.HitBox.TouchEnded:Connect(function(hit:BasePart)
		local hum = hit.Parent:FindFirstChild("Humanoid")

		if hum then
			local movedir = hum.MoveDirection.Unit
			local facevector = grass.RotateMain.CFrame * CFrame.Angles(math.rad(0), math.rad(0), math.rad(0))

			local TweenNormal = TS:Create(grass.PrimaryPart, tweenInfoNormal, {CFrame = facevector})

			TweenNormal:Play()
		elseif hit.Name == "Wheel" then
			
			local movedir = hit.AssemblyLinearVelocity

			
			local facevector = grass.RotateMain.CFrame * CFrame.Angles(math.rad(0), math.rad(0), math.rad(0))


			local TweenNormal = TS:Create(grass.PrimaryPart, tweenInfoNormal, {CFrame = facevector})

			TweenNormal:Play()
		end
	end)
end

---------------| WIND | -------------

while task.wait(0.2) do
	
	wind = script:GetAttribute("wind")
	windStrengh = script:GetAttribute("windStrengh")
	if wind then
		for i, grass in ipairs(GrassFolder:GetChildren()) do
			local movescalar = math.random(-2,2)
			local movedir = Vector3.new(math.random(1,2),math.random(1,2),math.random(1,2)).Unit
			
			
			
			local CFrameDifference = grass.RotateMain.CFrame * CFrame.Angles(math.rad(movedir.X * multiplier), math.rad(0), math.rad(movedir.Z * multiplier))

			local windtween = TS:Create(grass.PrimaryPart, tweenInfoTouched, {CFrame = CFrameDifference})
			windtween:Play()

		end
	end
end
1 Like

Cool! That works really well…

Is there a way to prevent the grass from going past 180 degrees though?

And if the grass is under the car to stay horizontal or something to prevent it from clipping through the car?

image

ill code a solution one second

1 Like

Not to bother you, but is there any update on this?

first solution i did was innefective im trying to make it very low peformance just some time

1 Like

Again, no rush but it has been about 5 days. Is there something I can help with?