Shared Table? Interactive Grass Issue

Hi!

I am making an interactive grass system in my game and am wondering what I should do…

So I have the server that is responsible for the movement of the grass (when a player walks over it, it will move accordingly).

I have the client who is responsible for the wind movement of the grass.

(I want the wind on the client, this way it can be optimized towards the user’s graphics settings)

So what do I do? When I have them in separate scripts (one client one server) the grass goes wild (I am 99% sure it is bc the table needs to be shared across the 2 scripts)

I have tried to use remote functions, but they are too slow.

Someone told me that I should use SharedTable | Documentation - Roblox Creator Hub, but I dont understand them and idk if they would work in this case

The goal is to replicate The Wild West - Roblox

Let me know if you have ideas!

Also here is the code (sorry if its messy)

Server (movement):

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)

-----| Debounce Dictionary |-----
local CoolDown = {}

local RS = game:GetService("ReplicatedStorage")
local CoolDowns = RS:WaitForChild("Grass")

CoolDowns.OnServerInvoke = function(Player)
	return CoolDown
end

for i, grass in ipairs(GrassFolder:GetChildren()) do

	grass.HitBox.Touched:Connect(function(hit:BasePart)
		if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Humanoid.Sit == false 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(math.clamp(movedir.X * multiplier, -180, 180)), 0, math.rad(math.clamp(movedir.Z * multiplier, -180, 180)))
				local TweenMove = TS:Create(grass, 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(math.clamp(movedir.X * multiplier, -180, 180)), 0, math.rad(math.clamp(movedir.Z * multiplier, -180, 180)))
				local TweenMove = TS:Create(grass, tweenInfoTouched, {CFrame = facevector})

				TweenMove:Play()

				task.wait(tweentime / cooldown_devision)
				CoolDown[grass] = false
				return
			end
		--]]
		elseif hit:GetAttribute("grass") then
			CoolDown[grass] = true
			local movedir = hit.AssemblyLinearVelocity.Unit * multiplier

			-- Calculate the yaw angle based on the car's movement direction
			local radians = math.atan2(movedir.Z, movedir.X)
			local yaw = math.deg(radians) + 180

			-- Create the new CFrame with a 20-degree lean and direction of the car's movement
			local facevector = grass.RotateMain.CFrame * CFrame.Angles(math.rad(20), math.rad(yaw), 0)

			local TweenMove = TS:Create(grass, tweenInfoTouched, {CFrame = facevector})
			TweenMove:Play()

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



	end)

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

		if hum and hit.Parent.Humanoid.Sit == false then
			local facevector = grass.RotateMain.CFrame * CFrame.Angles(0, 0, 0)
			local TweenNormal = TS:Create(grass, tweenInfoNormal, {CFrame = facevector})

			TweenNormal:Play()
		--[[
		elseif hit.Name == "Wheel" then
			local facevector = grass.RotateMain.CFrame * CFrame.Angles(0, 0, 0)
			local TweenNormal = TS:Create(grass, tweenInfoNormal, {CFrame = facevector})

			TweenNormal:Play()
		--]]
		elseif hit:GetAttribute("grass") then
			local facevector = grass.RotateMain.CFrame * CFrame.Angles(0, 0, 0)
			local TweenNormal = TS:Create(grass, tweenInfoNormal, {CFrame = facevector})

			TweenNormal:Play()
			return
		end
	end)
end

Client (wind):

local RS = game:GetService("ReplicatedStorage")  --
local CoolDowns = RS:WaitForChild("Grass")

local TweenService = game:GetService("TweenService")
local tweenInfoTouched = TweenInfo.new(0.2, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut)
local GrassFolder = workspace.Grass

while wait(0.2) do
	local wind = game.Workspace.GlobalWind
	local windStrength = wind.Magnitude
	if windStrength > 0 then
		for i, grass in ipairs(GrassFolder:GetChildren()) do
			local d = 1
			if d < 50 then -------------------- CHANGE TO PLAYER SETTINGS (ignore)
				local direction = wind.Unit
				local radians = math.atan2(direction.Z, direction.X)
				local yaw = math.deg(radians) + 180

				local random = Random.new()
				local final = windStrength / 20
				local x = random:NextNumber(2, 3) + final
				local z = random:NextNumber(2, 3) + final

				local movedir = Vector3.new(x, yaw, z)

				local CFrameDifference = grass.RotateMain.CFrame * CFrame.Angles(math.rad(movedir.X), math.rad(yaw), math.rad(movedir.Z))

				local windtween = TweenService:Create(grass, tweenInfoTouched, {CFrame = CFrameDifference})
				windtween:Play()
			end
		end
	end
end
1 Like

hopefully this will help.

Sorry for late reply… it doent seem to be working

its not changing any of the attributes

got it working…

30 chsssssssssssssssssssssssssssss

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.