Hello, so this is a weird issue I’ve come across and I was wondering if anyone knows how to avoid running into this problem. So, I have a renderstep that constantly rotates the primarypartcframe of a model. and i’ve noticed, gradually overtime the parts end up going out of place:
It should be like this:
This is my code:
game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
local Angles = CFrame.Angles(0, 0.0025 * deltaTime * 60, 0)
local Billboard = workspace.Billboard
Billboard:SetPrimaryPartCFrame(Billboard.PrimaryPart.CFrame * Angles)
end)
I only noticed this when I AFK’ed in-game for around 15 minutes and came back to find this weird occurrence
1 Like
I experienced the same problem. But when I’ve used CFrame.fromEulerAnglesXYZ instead of CFrame.Angles, the parts either didn’t move out of place at all or only a slightly bit. Other than that, I still don’t know a perfect solution to that.
This is what I had been using originally, then I used CFrame.Angles with the same exact results.
The only thing I could think of is using Welds. If that doesn’t work out, then I’ve got nothing else to say.
edit: Actually, this is probably wrong. I think you’re running into a limitation of SetPrimaryPartCFrame. I agree with @uhHappier, either use welds or do the relative offsets yourself.
You’re experiencing floating point precision errors, probably. Don’t set the next frame’s CFrame based on the last frame’s. Try something like this:
local angle = 0
local billboard = workspace.Billboard
local base = billboard.PrimaryPart.CFrame
local rotPerSecond = 0.02
game:GetService("RunService").RenderStepped:Connect(function(dt)
angle = angle + 2 * math.pi * rotPerSecond * dt
billboard:SetPrimaryPartCFrame(base * CFrame.Angles(0, angle, 0));
end)
1 Like
Here’s a better method that welds the parts together at the start of the game, then just manipulates the primary part’s CFrame directly (not tested).
local billboard = workspace.Billboard
local primaryPart = billboard.PrimaryPart
local rotPerSecond = 0.02
-- welds all the parts in `model` to `primaryPart` without moving them.
local function WeldTogether(model, primaryPart)
local inv = primaryPart.CFrame:Inverse()
local children = model:GetDescendants()
for i = 1, #children do
local child = children[i]
if (child ~= primaryPart and child:IsA("BasePart")) then
local weld = Instance.new("Weld")
weld.Part0 = primaryPart
weld.Part1 = child
weld.C1 = child.CFrame * inv
weld.Name = "Weld_" .. primaryPart.Name .. "_" .. child.Name
weld.Parent = primaryPart
end
end
end
local angle = 0
-- automatically weld the model together when the game starts. You could do this
-- manually, too (or even call WeldTogether from the command line while building)
WeldTogether(billboard, primaryPart)
local initCFrame = primaryPart.CFrame
game:GetService("RunService").RenderStepped:Connect(function(dt)
angle = angle + 2 * math.pi * rotPerSecond * dt
billboard.PrimaryPart.CFrame = initCFrame * CFrame.Angles(0, angle, 0)
end)
2 Likes