I achieved a similar style by utilizing magnitude aswell. With the magnitude of the oldPosition and newPosition, I did this to calculate the CFrame angle:
--v1
local m = cFrame.Position - oldCFrame.Position -- magnitude (as a vector3)
local angle = CFrame.Angles(rad(m.Z),rad(rotation),rad(-m.X))
With this the character rotates in the correct direction, but the angle value is so small that it’s barely noticeable. Therefore it’s good having a sway variable like here; the higher the value is, the more it sways:
--v2
local sway = 30 -- sway multiplier
local m = cFrame.Position - oldCFrame.Position -- magnitude (as a vector3)
local angle = CFrame.Angles(rad(m.Z*sway),rad(rotation),rad(-m.X*sway))
Lastly to make the animation smooth, I used TweenService. Instead of setting the part’s CFrame to the desired value, I tween it. That’s the basic princips of how I recreated it.
Here is my final script, I hope it’s not too hard to understand and maybe can help you get one step further to your goal.
-- LocalScript inside StarterPlayerScripts
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local plr = game.Players.LocalPlayer
local mouse = plr:GetMouse()
local mainPart = Instance.new("Part")
mainPart.Anchored = true
mainPart.CanCollide = false
mainPart.CanQuery = false
mainPart.CanTouch = false
mainPart.Size = Vector3.new(1,1,1)
mainPart.Parent = workspace
local oldCFrame = mainPart.CFrame
local rad = math.rad
-- tweakable variables
local tweenInfo = TweenInfo.new(.1,Enum.EasingStyle.Sine) -- the more time, the slower and smoother.
local offset = Vector3.new(0,0.5,0) -- can be used if part needs to be raised
local sway = 30 -- sway multiplier
RunService.Heartbeat:Connect(function()
if not mouse.Target then return end -- return if mouse is in the sky or smth
local cFrame = CFrame.new(mouse.Hit.Position+offset)
if cFrame ~= oldCFrame then -- If the part actually moved
local m = cFrame.Position - oldCFrame.Position -- magnitude (as a vector3)
local angle = CFrame.Angles(rad(m.Z*sway),0,rad(-m.X*sway))
cFrame *= angle
TweenService:Create(mainPart,tweenInfo,{CFrame = cFrame}):Play()
oldCFrame = cFrame
end
end)