# 3D Pendulum Script

With this code I have created a pendulum that works along the X and Y axis, how would I go about making this work for the Z axis as well?

``````local Bob = workspace.Bob
local Origin = workspace.Origin

local Length = (Origin.Position - Bob.Position).Magnitude

game["Run Service"].Heartbeat:Connect(function(dT)
theta = theta + aVelocity

local XArc = Length * math.sin(theta)
local YArc = Length * math.cos(theta)

Bob.Position = Origin.Position + Vector3.new(XArc, -YArc, 0)
end)``````

I’m not really too great with trigonometry but surely you’d use tangent to get the Z axis?

``````local ZArc = Length * math.tan(theta)
``````

By “working on the Z axis” do you mean you want it to work regardless of how the object is oriented?

``````...
Bob.CFrame = Origin.CFrame * CFrame.new(XArc, -YArc, 0)
...
``````
1 Like

Have you confused a pendulum with orbiting? Because what your code produces is object ‘Bob’ orbiting around object ‘Origin’ in a full circle.

A pendulum is essentially a swinging object which moves side to side. What you should use here is a sine wave which you give `tick()` as an argument to provide a continuous range from -1 to 1.

From this, you can continuously update Bob’s CFrame using Origin’s position, taking into account the origin’s rotation as well and applying an offset which is half the length of the pendulum.

``````game:GetService("RunService").Heartbeat:Connect(function()
local swing = math.sin(tick())

Bob.CFrame = (CFrame.new(Origin.Position) * CFrame.Angles(0, math.rad(Origin.Orientation.Y), swing) * CFrame.new(0, -Bob.Size.Y/2, 0))
end)
``````

This produces the following as a result and allows for rotating the origin and updating accordingly:

7 Likes

thanks, that is the type of behavior I am looking for.

Another question: how would I increase the range and allow the bob to swing to higher positions?

Apply a multiplier to the sine wave. For example if you double it, you’ll notice it will swing much higher.

``````local swing = math.sin(tick()) * 2
``````
1 Like