Issue with fulfilling 2 movements in one object [SOLVED]

  • What am I trying to do: I am trying to make a door with a handle which turns when the door is opened.

  • What’s the issue: I can’t find a way to make the handle turn while following the door, I’m using the “TweenService” and the only way I know to make an object move with that service is to anchor the object, the problem is that, when I anchor the handle, it stays static without following the door; if I don’t anchor the handle, it just falls, and if I use a WeldConstraint to avoid this, it doesn’t make its respective movement.

No anchoring:
I could not upload the video, but simply the handle follows the door as it should, however it does not present the rotation I placed in the script.

With anchor:

  • What have you tried: I’ve tried to solve it by using a WeldConstraint to make it follow the movement of the door, anchor the object and unanchor it, and even find another service to fulfill the movement.

Here’s the script:

local TweenService = game:GetService("TweenService")

local door = script.Parent.Door
local hinge = script.Parent.Hinge
local frontprompt = door.ProximityPrompt
local Behinddoor = script.Parent.Behinddoor
local Behindprompt = Behinddoor.ProximityPrompt
local DoorClose = script.Parent["Door Slams 5 (SFX)"]
local DoorOpen = script.Parent["Door Push Bar 2 (SFX)"]
local handleCenterback = script.Parent.handleCenterback -- Axis in which handleback will rotate (Also rotates on its own axis)
local handleCenterfront = script.Parent.handleCenterfront -- Axis in which handlefront will rotate (Also rotates on its own axis)
local handlefront = script.Parent.handlefront -- Front handle
local handleback = script.Parent.handleback  -- Back handle

local goalGirarFront = {} -- Goal when opening the door (Front handle)
goalGirarFront.CFrame = handleCenterfront.CFrame * CFrame.Angles(0, math.rad(0), -90)

local goalRegresarFront = {} -- Goal when closing the door (Front handle)
goalRegresarFront.CFrame = handleCenterfront.CFrame * CFrame.Angles(0, 0, 0)

local goalGirarBack = {} -- Goal when opening the door (Back handle)
goalGirarBack.CFrame = handleCenterback.CFrame * CFrame.Angles(0, math.rad(0), -90)

local goalRegresarBack = {} -- Goal when closing the door (Back handle)
goalRegresarBack.CFrame = handleCenterback.CFrame * CFrame.Angles(0, 0, 0)

local tweenhandlefrontInfo = TweenInfo.new(0.33)
local tweenfrontGirar = TweenService:Create(handleCenterfront, tweenhandlefrontInfo, goalGirarFront)
local tweenfrontRegresar = TweenService:Create(handleCenterfront, tweenhandlefrontInfo, goalRegresarFront)

local tweenhandlebackInfo = TweenInfo.new(0.33)
local tweenbackGirar = TweenService:Create(handleCenterback, tweenhandlebackInfo, goalGirarBack)
local tweenbackRegresar = TweenService:Create(handleCenterback, tweenhandlebackInfo, goalRegresarBack)

local goalOpen = {}
goalOpen.CFrame = hinge.CFrame * CFrame.Angles(0, math.rad(-90), 0)

local goalClose = {}
goalClose.CFrame = hinge.CFrame * CFrame.Angles(0, 0, 0)

local tweenInfo = TweenInfo.new(0.75)
local tweenOpen = TweenService:Create(hinge, tweenInfo, goalOpen)
local tweenClose = TweenService:Create(hinge, tweenInfo, goalClose)

local cooldownDuration = 2  -- Cooldown duration
local lastActionTime = 0
local isOpen = false

local function UpdatePrompts(actionText, cooldownTime) -- Sync between front and back door
	if cooldownTime > 0 then
		actionText = actionText .. " (" .. cooldownTime .. ")"
	end
	frontprompt.ActionText = actionText
	Behindprompt.ActionText = actionText
end

local function CancelarSonido(Cancelsound) -- Sound cancelling
	DoorOpen:Stop(Cancelsound)
	DoorClose:Stop(Cancelsound)
end

local function SetCooldown() -- Door cooldown
	lastActionTime = tick()
	local remainingCooldown = cooldownDuration
	while remainingCooldown > 0 do
		UpdatePrompts(isOpen and "Close" or "Open", math.ceil(remainingCooldown))
		wait(1)
		remainingCooldown = cooldownDuration - (tick() - lastActionTime)
	end
	UpdatePrompts(isOpen and "Close" or "Open", 0)
end

frontprompt.Triggered:Connect(function()
	print("Front prompt Triggered")
	local currentTime = tick()
	local elapsedTime = currentTime - lastActionTime
	local remainingCooldown = cooldownDuration - elapsedTime
	print("Cooldown remaining:", remainingCooldown)

	if remainingCooldown <= 0 then
		print("Cooldown complete, performing action")
		lastActionTime = currentTime
		if isOpen then
			print("Closing the door")
			CancelarSonido()
			print("Playing tweenfrontRegresar")
			tweenfrontRegresar:Play()
			wait(0.33)
			tweenClose:Play()
			tweenbackRegresar:Play()
			DoorClose:Play()
			DoorClose.TimePosition = 1.6
			isOpen = false
			UpdatePrompts("Open", 0)
		else
			print("Opening the door")
			CancelarSonido()
			print("Playing tweenfrontGirar")
			tweenfrontGirar:Play()
			wait(0.33)
			tweenOpen:Play()
			tweenbackGirar:Play()
			DoorOpen:Play()
			DoorOpen.TimePosition = 0.8
			wait(0.9)
			DoorOpen:Stop()
			isOpen = true
			UpdatePrompts("Close", 0)
		end
		SetCooldown()
	else
		print("Cooldown in progress")
	end
end)

Behindprompt.Triggered:Connect(function()
	print("Behind prompt Triggered")
	local currentTime = tick()
	local elapsedTime = currentTime - lastActionTime
	local remainingCooldown = cooldownDuration - elapsedTime
	print("Cooldown remaining:", remainingCooldown)if remainingCooldown <= 0 then
    print("Cooldown complete, performing action")
    lastActionTime = currentTime
    if isOpen then
      print("Closing the door")
      CancelarSonido()
      print("Playing tweenbackRegresar")
      tweenbackRegresar:Play()
      wait(0.33)
      tweenClose:Play()
      tweenfrontRegresar:Play()
      DoorClose:Play()
      DoorClose.TimePosition = 1.6
      isOpen = false
      UpdatePrompts("Open", 0)
    else
      print("Opening the door")
      CancelarSonido()
      print("Playing tweenbackGirar")
      tweenbackGirar:Play()
      wait(0.33)
      tweenOpen:Play()
      tweenfrontGirar:Play()
      DoorOpen:Play()
      DoorOpen.TimePosition = 0.8
      wait(0.9)
      DoorOpen:Stop()
      isOpen = true
      UpdatePrompts("Close", 0)
    end
    SetCooldown()
  else
    print("Cooldown in progress")
  end
end)

I’m pretty ignorant when it comes to CFrame, but all I can say is to try other constraints or a different movement method. RunService could complete this well. Just include a variable with the number of studs and decrease it over time. If you do try this method, trying welding every part to the “handleCenterfront” or whatever part is making the door open at the pivot shown in the video.

local Studs = 0.2 -- Change this to whatever you want.
local handleCenterfront = script.Parent.handleCenterfront
l
RunService.Heartbeat:Connect(function(deltaTime)
    if Studs > 0 then -- Remove this too if it gives you issues.
        handleCenterfront.CFrame *= CFrame.Angles(0, math.rad(0), math.rad(-Studs))
        Studs = Studs / 15 -- Change this if you want. I didn't test this script, so not sure if this bit works for every number you choose to set it to.
    end
end)

Use a Weld object and make them unanchored.

1 Like

Usually I just weld constraint the parts together then make an open and closed object of the door meaning I can just do

local OpenDoor = OpenDoor
local ClosedDoor = ClosedDoor

local Ts = game:GetService("TweenService")

local Info = TweenInfo.new(1.25,linear)

local TweenO =  Ts:Create(ClosedDoor.Door,Info,{CFrame = OpenDoor.Door:GetPivot()})

local TweenC = Ts:Create(OpenDoor.Door,Info,{CFrame = ClosedDorr.Door:GetPivot()})

--Then just trigger them here with TweenO being open door and TweenC being close door


Have you tried using a HingConstraint. With attachments set on the door and the handles, they will stay welded, but can be manipulated using the constraint.

Tried that but the handle won’t rotate

That’s because you need to edit Weld.C0/Weld.C1.

1 Like

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