I personally never tried doing anything similar, But i would recommend making the proximity prompt’s hold duration a large (not too large) number, And using two DateTime variables to determine the time the player started/stopped holding the proximity prompt to use the difference between the unix timestamps of those two DateTime variables as a factor on how fast the door opens
For this example i will tween the door with a speed based on how short the time between holding and letting go of the proximity prompt is (the lower the time, the higher the speed), But keep in mind this is just to give an idea on how it might work.
local tweenservice = game:GetService("TweenService")
local prox = script.Parent
local start = DateTime.now().UnixTimestampMillis*0.001
local maxtime = prox.HoldDuration
-- make the maxtime variable large but not too large
prox.InputHoldBegin:Connect(function()
start = DateTime.now().UnixTimestampMillis*0.001
end)
prox.InputHoldEnd:Connect(function()
local finish = DateTime.now().UnixTimestampMillis*0.001
local difference = math.max(0, finish - start)
local tweeninfo = TweenInfo.new(
math.min(difference, prox.HoldDuration),
Enum.EasingStyle.Bounce,
Enum.EasingDirection.In
)
-- play open/close tween here
end)
But about the door knowing which direction to go based off of its current orientation, I don’t know how to code that (atleast with a proximity prompt) but i have a suggestion that might help you brainstorm a solution for it.
Variable that determines if the door is open outwards, Closed, Or open inwards with the help of two attachments and math.sign(), The name of the variable for example will be “open”
The two attachments will be connected to the door, One of them 90 degrees clockwise, And the other 90 degrees counter-clockwise, I recommend changing the orientation of the attachments to face whichever orientation youd like the door to rotate to too.
As mentioned before, I don’t know how to check which side of the door the player is facing, So for the sake for this example i will assume its a boolean variable called “isfacingfront”
local isfacingfront
local open = 0
local tweenservice = game:GetService("TweenService")
local prox = script.Parent
local inwards : Attachment = prox.Parent.Inwards
local outwards : Attachment
-- assuming the proximity prompt is under the door that contains the 2 attachments i mentioned previously.
local tween = {
IN = tweenservice:Create(
prox.Parent,
tweeninfo, -- i know i havent set this variable but just pretend it's set to your preferred arguments
{CFrame = inwards.WorldCFrame}
),
OUT = tweenservice:Create(
prox.Parent,
tweeninfo,
{CFrame = outwards.WorldCFrame}
)
}
prox.InputHoldEnd:Connect(function()
local attachment = if isfacingfront then inwards else outwards
if math.abs(math.sign(attachment.Orientation.Y)+open) < 2 then
tween[if isfacingfront then "IN" else "OUT"]:Play()
-- any code you want to add
open += math.sign(attachment.Orientation.Y)
else -- door goes the other way (towards the player)
tween[if isfacingfront then "OUT" else "IN"]:Play()
-- any other code you want to add
open -= math.sign(attachment.Orientation.Y)
end
end)
The two scripts aren’t supposed to be connected or anything by the way, But sorry for any bad typing/formatting i haven’t noticed.
Let me know if you need any explanation on this.