How to "swivel bobbing" with gui Frames?

I need to apply a effect on a frame so it’s movement is a little delayed when matching with the viewport.
I have made a simple but not efficient script to do that for a example:
giphy

local plr = game:GetService("Players").LocalPlayer
local camera = workspace.CurrentCamera
repeat wait() until plr.Character
local p = Instance.new("Part")
p.Size = Vector3.new(0.25,0.25,0.25)
p.Position = plr.Character.Head.Position + Vector3.new(0,1,2)
p.CanCollide = false
p.Parent = workspace -- workspace not character so we can see it in first person
local attachmentA = Instance.new("Attachment", p)
local attachmentB = Instance.new("Attachment", plr.Character.Head)
attachmentB.Position = Vector3.new(0, 0.5, -2)
local mover = Instance.new("AlignPosition", p)
mover.Attachment0 = attachmentA
mover.Attachment1 = attachmentB
spawn(function()
while true do
local vector, onScreen = camera:WorldToScreenPoint(p.Position)
local screenPoint = Vector2.new(vector.X, vector.Y)
script.Parent.Frame.Position = UDim2.new(0,screenPoint.X - 75,0,screenPoint.Y -75)
game:GetService("RunService").RenderStepped:Wait()
end
end)

model.rbxm (2.8 KB)
I need something simpler than that, more responsive and something that does not use parts like it does.

Any help would be very appreciated!

2 Likes

You should get into the habit of formatting your code with tabs or spaces. Helps other people (and me) read your code more efficiently.

Also, I don’t think that spawning a function and applying a while-loop is efficient in itself.

local RunService = game:GetService("RunService")
local Gui = script.Parent
RunService.RenderStepped:Connect(function(step)
    local vector, onScreen = camera:WorldToScreenPoint(p.Position)
    local screenPoint = Vector2.new(vector.X, vector.Y)
    gui.Frame.Position = UDim2.new(0,screenPoint.X - 75,0,screenPoint.Y -75)
end)

Full Script

local RunService = game:GetService("RunService")
local Player = game:GetService("Players").LocalPlayer

-- https://developer.roblox.com/en-us/api-reference/property/Player/Character
local Character = Player.Character
if not character or not character.Parent then
    character = Player.CharacterAdded:wait()
end

local Camera = workspace.CurrentCamera
local Gui = script.Parent

local Part = Instance.new("Part")
Part.Size = Vector3.new(0.25,0.25,0.25)
Part.Position = Character.Head.Position + Vector3.new(0,1,2)
Part.CanCollide = false
Part.Parent = workspace

local attachmentA = Instance.new("Attachment", Part)
local attachmentB = Instance.new("Attachment", Character.Head)
attachmentB.Position = Vector3.new(0, 0.5, -2)

local mover = Instance.new("AlignPosition", Part)
mover.Attachment0 = attachmentA
mover.Attachment1 = attachmentB

RunService.RenderStepped:Connect(function(step)
    local vector, onScreen = Camera:WorldToScreenPoint(Part.Position)
    local screenPoint = Vector2.new(vector.X, vector.Y)
    Gui.Frame.Position = UDim2.new(0,screenPoint.X - 75,0,screenPoint.Y -75)
end)

Hope this helps!

3 Likes

Hey! the code that was shown above was just a demonstration, it was done in a hurry, just to be an example of what I’m trying to do, that all the code was made just to be used in the gif, it would not fit the full project I am working on (I’m looking for somethng that is just a script without the need of adding anything else to make it work) but thanks for the formatting tips anyway!

1 Like