I have rotating lasers in my game. While using run, the script works great and the laser union spins fine like so:
While playing the game(in studio or in the published client), the lasers are frozen and do not spin:
There are no errors in output relating to this script.
Here is the script:
local Angle = math.deg(.01)
local Part = script.Parent
RunService:BindToRenderStep("Rotation", 199, function(dt)
if Part.Parent then
Part.CFrame = Part.CFrame * CFrame.Angles(0, Angle * dt, 0)
else
RunService:UnbindFromRenderStep("Rotation")
end
end)
I’m willing to wager that the issue lies in the kind of script you’re running. Do you think it would be possible to recreate the functionality of these lasers within a LocalScript instead?
Well, I’m no expert on the engine, but I’ve honestly had much better luck with doing things like this on the client, as it’s generally more reliable and snappy. That, coupled with the video footage you shared, leads me to believe that the changes to the lasers aren’t being replicated properly.
Either changing the server code or localizing the lasers turning would be your best bet.
I think that instead of doing renderstepped do this.
while wait(3.61) do
for i = 1, 360, 1 do
part.CFrame = Part.CFrame * CFrame.Angles(0, 0, i)
--or
local iv = math.deg(i)
part.CFrame = Part.CFrame * CFrame.Angles(0,0,iv)
end
end
This wont work, it’ll just execute the code in the body of the while loop and then wait 3.6 seconds. To solve the problem you need to use RunService.Heartbeat or something else entirely as renderstepped does not fire on the server.
See:
I’d be inclined to agree with @glossydon, since if you render it on the server it’ll look like it’s skipping for the clients. You would need to think of a way to validate if a player actually got hit by a laser since you shouldn’t trust the client.
I ended up using RunService.Heartbeat like you said in a script. Thank you for the help! Here is the final script for anyone elso who finds this post and needs help:
local r = 1 --rotations per second
local RunService = game:GetService("RunService")
local part = script.Parent
while true do
local dt= RunService.Heartbeat:Wait()
part.CFrame = part.CFrame * CFrame.fromEulerAnglesXYZ(0,r*dt,0) --You can put r*dt anywheres in (0,r*dt,0) depending on the axis you want it to rotate on.
end
The damaging part of the laser is handled by a function script in ServerScriptService that gets all the lasers in the game with minimal network usage.
You may want to use a connection, as a loop will terminate when an error propagates. This may not be an issue for this function, but it’s better in the long term as you add more things to your game:
local r = 1 --rotations per second
local RunService = game:GetService("RunService")
local part = script.Parent
RunService.Heartbeat:Connect(function(dt)
part.CFrame = part.CFrame * CFrame.fromEulerAnglesXYZ(0,r*dt,0) --You can put r*dt anywheres in (0,r*dt,0) depending on the axis you want it to rotate on.
end
Running scripts on the client makes the game very exploitable. Exploiters can see scripts in the Workspace, Local scripts should be solely used to handle the client. There is an easier way to do this @DaBisawesome123, you might want to spin all of those laser by putting them all in a model and creating a part as the axis and weld the lasers to it, then spin the PrimaryPart separately.
while true do
wait()
script.Parent.CFrame = script.Parent.CFrame * CFrame.fromEulerAnglesXYZ(0, math.pi/35, 0)
end
Right now I have them in a union using a regular serverscript to rotate them, not a localscript. The reason I am not using a local script is the same reason as which you pointed out, it makes it exploitable. Is there a benefit to your model method with welds vs my union method? Also, is there a benefit to your script?