I’ve decided to simplify things by switching to a paid plugin. It installs everything you need with one click and updates outdated code easily. This means I won’t have to provide separate game files and models for each version anymore. It also includes tagging features, so you don’t need additional plugins like Tag Editor to tag and untag things.
Hey, so mine doesn’t have major features that differentiate it from other free interactive grass scripts, the differences are mainly just simplicity since it takes like 10 seconds to set up, and being able to configure with the vast config in mine to adjust everything to your liking, I know this isn’t enough to justify mine being $5, which is why I’m planning on figuring out solutions as to more optimization, other players being able to see you move around in grass without lag, aswell as support for shaking your grass like how the wind shake module does, cause rn if you try to combine this with the windshake module its buggy. I’m looking for feedback on how I can improve my plugin to make it stand out, since right now it was just released today and doesn’t stand out that much.
Yes, I’m using local scripts on the client. I’m not entirely sure how I could make it so others can see the movement but maybe remote events and fire it all to clients? so it wont tween the grass on the server but on everybodies client
WindShake = {
Enabled = false, -- Enable/disable wind shake effect
ScriptPath = Players.LocalPlayer.PlayerScripts.WindControllerClient, -- Path to the wind shake script, not the module, the script that requires it
},
New Notification UI
UI Notifications will pop up when you install the plugin, tag grass, untag grass, and uninstall the plugin, as well as errors. It will also include sounds, rather than only using the output to print messages!
What this is really good for is making tall grass that is different and unique apart from terrain grass.
In terms of performance advice, use ConnectParallel() where possible, actors, task.synchronize, task.desynchronize, and --!native, also occlusion culling for excluding objects physics not in view
Script now uses actors, task.synchronize, task.desynchronize, and --!native.
Occlusion Culling
Option to make grass not visible when the camera is not looking at it, although it’s not well optimized and leaving it not enabled is more smooth rather than enabled, spent like 10 minutes making it and realized its pointless and buggy so I scrapped it, but you can still enable it if you want I guess.
Yes, it uses actors. It uses a radius system to disable physics for grass that arent near you, so the game doesn’t constantly listen for those touch events. It also uses tags since tags are faster than looping through for example children in a folder or descendants in workspace with the names “Grass”. You should not experience any lag, especially if your grass is spread out and is a decal or has low polygons. Also has an okay occlusion culling system which can be toggled on or off which will move the grass not visible in the players camera to replicatedstorage.
In terms of occlusion culling, ROBLOX already does rendering occlusion culling, what your code should do is use that to determine whether to animate the grass or not.
local camera=workspace.CurrentCamera
local function IsInView(object,cameraViewportSize,key)
local objectPosition = camera:WorldToViewportPoint(object.Position)
-- Check if the object is within the camera's viewport
--print(objectPosition)
if objectPosition.X <= cameraViewportSize.X and
objectPosition.Y <= cameraViewportSize.Y and
objectPosition.Z > 0 then -- Z > 0 means the object is in front of the camera
return true
else
return false
end
end
local location=game.Players.LocalPlayer.PlayerScripts:WaitForChild("SmartBone-Actors")
local function dontcullsmartbone()
local cameraViewportSize = camera.ViewportSize
for i,v in location:GetChildren() do
v.Runtime.Rendered.Value=true
end
end
local function cullsmartbone()
local cameraViewportSize = camera.ViewportSize
for i,v in location:GetChildren() do
if v.Runtime:FindFirstChild("Sourceobj") and IsInView(v.Runtime.Sourceobj.Value,cameraViewportSize) then
v.Runtime.Rendered.Value=true
if v.Runtime.Enabled==false then
v.Runtime.Enabled=true
end
else v.Runtime.Rendered.Value=false
end
end
end
local camcfram=camera.CFrame
while true do
task.wait(.6)
if camcfram~=camera.CFrame then
--pcall(function()
cullsmartbone()
--dontcullsmartbone()
--end)
end
end
This is an example usage of occlusion culling that does not use many resources, but does not include the bounding box which is more relevant to larger objects. In my experience if you want to use that I would not do it every frame, but just use it to determine if you should animate the grass or not. Finally, a distance check could be done on objects in view, check if the grass should be animated or perhaps the fidelity of the animation such as the frames per second.
Alright, I’ll look into it. Isn’t occlusion culling gonna be a little unnecessary if I already have a radius system that disables the physics when I’m not near the grass?
well the radius system is good because it’s distance, occlusion culling is for objects that are not in view of the camera, such as objects behind the player’s field of view. It’s important not to do it every frame though as that could cause performance issues, this would allow the code to skip animating grass that is not seen by the player. It would be best to incorporate it into the radius calculation, so if the object passes the radius calculation it is checked for occlusion or vice versa
I’ve taken on the challenge of making the Interactive Grass plugin strictly typed. It’s now 99% complete! Additionally, I’ve optimized it a tad bit for better performance. Feel free to reach out on Discord if you’re interested: 6laise