Move a Hinge Based Door to Desired Location

What do you want to achieve?
I have a hinge based door system for a car and I want the door to open and close when entering or exiting the DriveSeat

What is the issue?
Can’t find a way to make the door move to the desired location

What solutions have you tried so far?
Tried using ai but no matter how hard I try I couldnt get them to work as I wanted and couldn’t find any tutorials related to bringing hingeconstraints based objects to desired locations

Please be as descriptive as you can because I lack of major scripting experience but I’ll try my best

-- Script.lua by VanillaEdge
-- For Left Door

STRUTS_ENABLED = false
MAX_ANGLE = 80
PLAYER_POWER = 80
STRUT_POWER = 10

-- Variables
local model = script.Parent
local doors = model.Parent
local car = doors.Parent.Parent

local driveSeat = car.DriveSeat
local openSound = doors.OpenSound
local closeSound = doors.CloseSound

local hingeConstraint = model.Hinge.HingeConstraint
local dragDetector = model.MainPart.DragDetector
local bodyForce = model.MainPart.BodyForce
local weld = model.MainPart:WaitForChild("Weld")

local lastDragFrame = dragDetector.DragFrame
local doorMovedByPlayer = false
local doorIsOpen = false
local bufferAngle = 0.3

-- Functions
local function updateLockState(state)
	weld.Enabled = state
	hingeConstraint.LowerAngle = state and 0 or MAX_ANGLE
end

local function updateDoorState()
	local currentAngle = hingeConstraint.CurrentAngle
	
	-- Play sound based on door state
	if currentAngle >= bufferAngle and not doorIsOpen then
		openSound:Play()
		doorIsOpen = true
	elseif currentAngle < bufferAngle and doorIsOpen then
		closeSound:Play()
		doorIsOpen = false
	end
	
	-- Apply strut force
	if STRUTS_ENABLED and currentAngle >= bufferAngle then
		local lookVector = driveSeat.CFrame.lookVector
		bodyForce.Force = lookVector * STRUT_POWER
	else
		bodyForce.Force = Vector3.new(0, 0, 0)
	end
	
	-- Automatically lock/unlock door
	if not doorMovedByPlayer then
		local state = currentAngle < bufferAngle
		updateLockState(state)
	end
end

local function onDragDetectorChanged()
	if lastDragFrame ~= dragDetector.dragFrame then
		doorMovedByPlayer = true
		lastDragFrame = dragDetector.dragFrame
		updateLockState(false)
	end
end

-- Connections
dragDetector:GetPropertyChangedSignal("DragFrame"):Connect(onDragDetectorChanged)

-- Initialise
dragDetector.Enabled = true
dragDetector.MaxForce = PLAYER_POWER
dragDetector.MaxTorque = PLAYER_POWER

hingeConstraint.LowerAngle = 0
weld.Enabled = false

while true do
	task.wait(0.1)
	updateDoorState()
	doorMovedByPlayer = false
end

The door is under Misc-Doors-FL

Doors.rbxm (262.1 KB)

2 Likes

you can try using a goal cframe

its

local hinge = --hinge object

local rot = {}
rot.CFrame = hinge * CFrame.Angles(0, 0, 0) -- this internal angle is the target. use math.rad for angling properly

-- you also need a second rot variable but with the closed angle (which should just be 0,0,0)

i might be slightly off on that tho

2 Likes

Thats not a proper fix, well it works but pretty much drags behind the car when the car is moving
The problem is that it calculates positions based on the car’s current location, but when the car moves during the tween, those CFrame targets become outdated.
Let me know if you have a fix for this

If I were you and I was having this issue I’d try one of 2 things:

#1 reduce the mass of the door so it has less inertia when the car is moving, could be finely tuned to look good

#2 use align position on the doors.
You could create an attachment for open and closed door positions in the car, then when you want to open the door, you just swap the align position attachment0 to be the open/closed attachment

Lmk if this works!