How to do pendulum swing on models?

I’m attempting to simulate a pendulum swing on a model with many parts in it. I’ve essentially copied the code from this tutorial, but it doesn’t work: Making a simple Pendulum Model without physics - #9 by BanishAlt

Here’s my code:

game:GetService("RunService").Heartbeat:Connect(function()
	for _, broccoliSwing: Model in broccoliSwings:GetChildren() do
		local angVel = 0
		local fixedPoint = workspace.FixedPoint
		local length = (fixedPoint.Position - Vector3.new(broccoliSwing:GetPivot())).Magnitude
		local XArc = length * math.cos(theta)
		local YArc = length * math.sin(theta)
		broccoliSwing:PivotTo(CFrame.new(Vector3.new(XArc, YArc, 0), Vector3.new()) + fixedPoint.CFrame.Position)
		angVel = angVel + (0.01*math.sin(theta))
		theta = theta + angVel
	end
end)

image
The chain and the broccoli should both be swinging.

2 Likes

Bump --Minimum characters needed

2 Likes

my original code followed the tutorial, so you will have to adjust the Bob and Origin in the default script for it to work

local Bob = workspace.BroccoliSwing.Bob -- change the part you want to swing to this
local Origin = workspace.fixedPoint

--//Next we get the Arm's length ( in this case the distance from the Origin to the Bob
--//We don't use an actual rope constraint or anything else, we can use a beam for aesthetics

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

--//Okay alot of people may get confused by this part, but now we want a predefined
--//Angle for the sake of this tutorial, so we'll go with an angle of 45 deg
local theta = math.deg(360)
if theta == 360 or 0 then
	theta = 1 -- fail safe
end
--//Value for angular velocity which we will use later
local angVel = 0
local realdrag = 1
--//Next we create our function to compute the Bob's Motion per Oscillation
local function Compute(deltaTime)
	--//Using Trigonometry we want to find the arc of the Bob's Displacement on each axis
	--//The reason we multiply the length by the the Arc is so that we take the Length of the arm
	--//Into account when returning the arc of the angle on the axis.. 
	--//In simple terms, we're offsetting the arc from the origin point by the Length

	local XArc = Length * math.sin(theta)
	local YArc = Length * math.cos(theta)
	local YDrag = Length * math.cos(360-theta)
	local function sqrtNegative(value)
		local funny = (Vector3.yAxis*value).Unit.Y
		return math.sqrt(math.abs(value))*funny
	end
	local drag = math.clamp(realdrag*(sqrtNegative(YDrag/2)),realdrag/1.77,realdrag*1.77)*math.sqrt(1.77) -- so it cant be too strong
	local speed = 0.75
	print(drag)
	if drag ~= drag then
		drag = 1.25 -- prevents part from disappearing
	end

	angVel = (angVel - angVel * drag * deltaTime) + math.sin(theta) * deltaTime * speed
	--//Okay so now we lerp the Bob's CFrame, WHILE keeping it relative to the Origin Point
	local cframeBase = Bob.CFrame:Lerp(CFrame.new(Vector3.new(XArc , YArc, 0) , Vector3.new()) + 
		Origin.CFrame.Position, 0.4)
	Bob.CFrame = cframeBase
	theta += angVel
end

--//To constantly update the CFrames and Values
game:GetService("RunService").Heartbeat:Connect(Compute)

Then add additional code to make the chain follow the bob by setting up offsets (i dont know how the model works so i cant do this for you)

1 Like

I’ve got a swing motion going now, I’m just having problems angling the chain towards the fixed point. How would I do that?


That’s what it looks like right now, and it should be turning as it goes across the arc

maybe set up a function that updates the rotation w/ a time function to make it delay
like make the first chain the rotation point then make the broccoli and the second chain part have the cframe of the past one (again, check it using a time event and setting the offsets via that)

for ref i mean like doing

local lastTime = 0
if time() - lastTime > 0.25 then
-- update cframe
elseif time() - lastTime > 0.5 then
-- update 2nd cframe
   lastTime = time()
end
1 Like