Make a part rotate under the player's weight

In a nutshell, i want the part to change its’ rotation on the X axis only when player steps on it, alas mimicking the physics
Example 1:


Example 2:

1 Like

Hey, @subto_deraxileonyt my code is made “with fast hands” but I hope it helps!

local Part = script.Parent

Part.Touched:Connect(function(obj)
	if game.Players:GetPlayerFromCharacter(obj.Parent) then
		local player = game.Players:GetPlayerFromCharacter(obj.Parent)
		local character = player.Character or player.CharacterAdded:Wait()
		local totalMass = 0
		
		task.spawn(function()
			for index, value in pairs(character:GetDescendants()) do
				if value:IsA("Part") or value:IsA("MeshPart") or value:IsA("BasePart") then
					totalMass += value:GetMass()
				end
			end
			
			if totalMass > 0 then
				--Use the angle you like on the part
			end
		end)
	end
end)

Hope it helps!

1 Like

It indeed works, I put part.CFrame = part.CFrame * CFrame.Angles(math.rad(totalMass / 50), 0, 0), although it rotates only in one direction(to the left) - is there any way to “detect” the player’s position, so it would rotate accordingly?

You could try with CFrame.LookVector, for more info go here: https://create.roblox.com/docs/it-it/reference/engine/datatypes/CFrame#LookVector

If there’s any other question feel free to ask @subto_deraxileonyt

Or you could just use Character.PrimaryPart.CFrame with your CFrame needs.

Worked well, thanks!

Here’s the script, if anyone needs it:

local p = script.Parent
local rotSens = 0.01
local massScale = 25
local maxA = math.rad(45)
local touchingPlayers = {}

p.Touched:Connect(function(obj)
	if game.Players:GetPlayerFromCharacter(obj.Parent) then
		local player = game.Players:GetPlayerFromCharacter(obj.Parent)
		if not touchingPlayers[player] then
			touchingPlayers[player] = true
			local character = player.Character or player.CharacterAdded:Wait()
			local rootPart = character:FindFirstChild("HumanoidRootPart")

			if rootPart then
				local function rotateWhileTouching()
					while touchingPlayers[player] do
						local totalMass = 0

						for _, value in ipairs(character:GetDescendants()) do
							if value:IsA("Part") or value:IsA("MeshPart") or value:IsA("BasePart") then
								totalMass += value:GetMass()
							end
						end

						if totalMass > 0 then
							local direction = (rootPart.Position - p.Position).Unit
							local rotationAngle = -math.atan2(direction.X, direction.Y) * rotSens

							local massRotation = math.min(math.rad(totalMass / massScale), maxA)
							local rightSide = (rootPart.Position - p.Position):Dot(p.CFrame.RightVector) > 0
							massRotation = rightSide and -massRotation or massRotation
							p.CFrame = p.CFrame * CFrame.Angles(massRotation, 0, rotationAngle)
						end

						task.wait()
					end
				end

				task.spawn(rotateWhileTouching)
			end
		end
	end
end)

p.TouchEnded:Connect(function(obj)
	if game.Players:GetPlayerFromCharacter(obj.Parent) then
		local player = game.Players:GetPlayerFromCharacter(obj.Parent)
		touchingPlayers[player] = false
	end
end)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.