Rigged Doors Script

Sorry this post is a bit long, but it could potentially be useful for everyone if we can find a solution.

Hello, I’m trying to create a Door System with a Rig + Animation Controller to animate the door. But I’m having trouble creating a proper script.
I’d like it to stay open as long as the player is near the door, and close it once he’s gone.

I thought of creating a transparent part, detecting when a player Touch the part to animate the door to open it, then detect when the Touch Ended to animate the door to close it.

But when the door is open, I can only think of two ways to keep it open (as you know, when an animation stops, the object returns to its initial position):
1/ Put a second transparent door that I make visible when the opening animation is finished, when the Touch Ended, I animate this second door to close it, then I make it transparent, and I make the first door visible again.

2/ Create a door opening animation that stays open for a very long time (2 minutes…), and when the Touch Ended, I animate the door close with a Priority.Action2 to override the first animation, when the door is closed, I stop both animations.

Maybe there could be better solution that i didn’t know or didn’t think about …

Here is a first script i’ve made to see what happens. If you have some tips or Advice, i take it ! Thanks for reading !

local AnimOpenValue1 = script.OpenDoor1
local AnimCloseValue1 = script.CloseDoor1

for i,v in workspace.Doors:GetChildren() do
	local AnimOpen1 = v.AnimationController.Animator:LoadAnimation(AnimOpenValue1)
	local AnimClose1 = v.AnimationController.Animator:LoadAnimation(AnimCloseValue1)
	AnimOpen1.Priority = Enum.AnimationPriority.Action
	AnimClose1.Priority = Enum.AnimationPriority.Action
	local db = false
	v.TouchDetectDoor.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild('Humanoid') then
			if db == false then
				db = true
				AnimOpen1:Play()
			end
		end
	end)
	v.TouchDetectDoor.TouchEnded:Connect(function()
		AnimClose1:Play()
		task.wait(AnimClose1.Length)
		db = false
	end)
end
5 Likes

Just off the top of my head, I think you can change the position of the animation being played, such as moving it back to a certain keyframe, to keep it looping until you need it to close.

3 Likes

Maybe TimePosition?

3 Likes

there is a great module for this called ZonePlus

Which easily lets you hook up responsive “Zones”

local Zone = require(game:GetService("ReplicatedStorage").Zone)
local container = workspace.AModelOfPartsRepresentingTheZone
local zone = Zone.new(container)

zone.playerEntered:Connect(function(player)
    -- open door
end)

zone.playerExited:Connect(function(player)
    -- close door
end)
``
3 Likes

and let me know if this didnt work id be more than happy to help

(if it did . . . GIMMIE THAT CHECKMARK!!!)

2 Likes

So i can see some good resultats with the second alternative i said, so the opening animation has a one minute length. I removed Touch Ended Function , i just detect on a loop the magnitude between the character RootPart and the door, if it’s over 4 then i play the close animation then i stop both animations. It would be pretty similar than with TimePosition.

2 Likes
	local AnimClose1 = v.AnimationController.Animator:LoadAnimation(AnimCloseValue1)
	AnimOpen1.Priority = Enum.AnimationPriority.Action
	AnimClose1.Priority = Enum.AnimationPriority.Action2
	local db = false
	v.TouchDetectDoor.Touched:Connect(function(hit)
		if hit.Parent:FindFirstChild('Humanoid') then
			if db == false then
				db = true
				AnimOpen1:Play()
				task.wait(1.5)
				local RootPart = hit.Parent:FindFirstChild('HumanoidRootPart')
				if RootPart then
					while task.wait(0.1) do
						local magnitude = (RootPart.Position - v.TouchDetectDoor.Position).magnitude
						if magnitude > 4 or RootPart.Parent == nil then
							AnimClose1:Play()
							task.wait(AnimClose1.Length -0.2)
							AnimOpen1:Stop()
							db = false
							break
						end
					end
				end
			end
		end
	end)
end
3 Likes

Hi thank you for you answer,

I tend to prefer scripts writed by myself to modules that i don’t understand (even when they’re more efficient than my way). Do you have any idea how this module detects that the player is in a zone? Because it seems that the Touch function isn’t used?

2 Likes

the .Touched event is notoriously buggy and can be inaccurate. ZonePlus is a lot more reliable, resourceful, and all around easier to use

here is a really good video on it

As for the door animation, i think TweenService could simplify this

4 Likes

I’ll keep updating this post until i find (or someone find) the best way to animate a door (using rigs)

2 Likes

I have a door that (not by animation, rather tweening cframes) will open when a player gets close, and only close when no players are near.

I used an invisible part, with a Touched event that then puts the player id of the player who touched it in a list.

If ever the list is not empty, The door remains open, and if the magnitude of the players in the list is greater than a value, I remove them from the list. Also if a Player has disconnected, they are removed from the list. I do this check by looking for each player in the list by their userid (which is what the list stores) if ever that returns nil, that userid is removed.

Just thought I would share what worked for me.

4 Likes

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