Hello! I am currently working on overhauling an equips system for my game, where the player can equip different styles of “halos” to wear over their head, which is a model welded to its primary part, which is welded to the player’s head. I experienced a rather weird issue that I have not been able to find a solution to yet. Before I describe the issue since it is extremely specific, here is some context. Some of these equippable halos have parts that rotate around the halo. Originally, to make these parts rotate each halo with rotating parts had a very short local script inside it that multiplied the Weld’s C0 Orientation in very small increments using RunService, an example below.
game:GetService("RunService").Stepped:Connect(function(Blah, DT)
pcall(function()
script.Parent.Base.spinny.C0 *= CFrame.Angles(0, math.rad(3) * (DT * 30), 0)
end)
end)
While this worked fine for the halo that the local player was wearing, halos that other players would wear did not rotate accordingly. This has been a minor visual bug that I’ve always wanted to fix, so I decided to scrap the small scripts in each halo altogether and make a function inside the halo equip system that detects if the halo has rotating parts and rotates them accordingly. Since having a bunch of RunService.Stepped functions for all the halos in the server was very performance heavy, I decided instead to utilize Tweens, which I was much more familiar with anyway. The function ended up looking like this:
function SetupHaloSpin(player,halo)
local spinTweeny = nil
local spinTweeny2 = nil
if halo.Name == "Developer" then--all of these if statements just create the tweens specific to the halo, they tween the Welds C0 orientation so that it rotates while still staying true to the players orientation
spinTweeny = Tweens:Create(halo.Base.Circles,TweenInfo.new(2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1),{C0 = halo.Base.Circles.C0 * CFrame.Angles(0,math.rad(180),0)})
elseif halo.Name == "Cave" then
spinTweeny = Tweens:Create(halo.Base["crystals small"],TweenInfo.new(2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1),{C0 = halo.Base["crystals small"].C0 * CFrame.Angles(0,math.rad(180),0)})
spinTweeny2 = Tweens:Create(halo.Base["crystals big"],TweenInfo.new(0.67,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1),{C0 = halo.Base["crystals big"].C0 * CFrame.Angles(0,math.rad(180),0)})
elseif halo.Name == "Clouds" then
spinTweeny = Tweens:Create(halo.Base.Cloud,TweenInfo.new(2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1),{C0 = halo.Base.Cloud.C0 * CFrame.Angles(0,math.rad(180),0)})
elseif halo.Name == "DC" then
spinTweeny = Tweens:Create(halo.Base.Rotate,TweenInfo.new(2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1),{C0 = halo.Base.Rotate.C0 * CFrame.Angles(0,math.rad(180),0)})
elseif halo.Name == "Snow" then
spinTweeny = Tweens:Create(halo.Base.spinny,TweenInfo.new(2,Enum.EasingStyle.Linear,Enum.EasingDirection.Out,-1),{C0 = halo.Base.spinny.C0 * CFrame.Angles(0,math.rad(180.001),0)})
end
spinTweeny:Play()--play the created tween, dont need to worry about it being nil cuz this function only gets called if rotating parts are detected
if spinTweeny2 ~= nil then
spinTweeny2:Play()--play secondary tween if necessary
end
halo:GetPropertyChangedSignal("Parent"):Connect(function()
if halo.Parent ~= player.Character then
spinTweeny:Cancel()--stop the tween if the halo is unequipped or refreshed upon respawn
if spinTweeny2 ~= nil then
spinTweeny2:Cancel()
end
end
end)
end
I threw the function together and everything worked exactly how I wanted it to, until I discovered the extremely strange bug that led me to creating this post.
For some odd reason, terrain water does not like it when the rotating part uses a tween to rotate itself instead of RunService.Stepped. I’ve attached a recording of the odd behavior that I found while testing it out. The player can not float all the way up to the top of the water, and sort of gets stuck right when the top of the halo model hits the surface of the water. It makes it very annoying for both entering and exiting areas of water terrain, and I am completely unsure why specifically tweening C0’s orientation caused this when continuously updating it with RunService did not. Switching over to a halo that doesn’t have rotating parts proves that it is an issue with the tweens. At one point I did try recreating the tween system using RunService.Stepped instead, and it fixed the bug but was EXTREMELY laggy so it is not something I want to do. I’ve tried experimenting with all sorts of properties and have found no solution. If anyone understands why it is doing this or any alternative way I can go about this system without being extremely performance heavy, please do let me know! I wanted to try asking about it before filing a bug report on the behavior.
Additionally, to make sure it was in fact the tween that was causing it to happen and nothing else about the equip system, in a test place I made a script that simply welded a part to the player’s head and tweened the welds C0 orientation, and it did the exact same thing. Not sure why but its interesting! If I’m missing any useful information regarding this issue please let me know and I’ll do my best.