Elevator not working properly

I made an elevator some time ago but i can’t seem to find how to fix an error where you phase trough the door while moving or be on freefall while its going down (with phasing i mean that you kind of get your legs onto the floor while moving and if you go with more speed you can phase entirely trough the floor)


i tried using RunService but its just too slow or got a stuttering movement, at this point the elevator is using TweenServicePlus and i want to get ideas on how to properly remove that phasing problem, or how to remove the stuttering with RunService
i also tried Welding the character but it made some weird things while trying to make it not look like you were weld

1 Like

Can you show us the script for your elevator? Please provide us any scripts that handles the elevator’s moving logic.

ignore the spanish things

local ElevatorModule = {}
TweenServicePlus = require(game.ReplicatedStorage.TweenServicePlus)
RunS = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
function ElevatorModule.ElevatorFunction(elevator)
	local floors = elevator.Parent.Parent.Elevador.ElevatorPoints:GetChildren()
	local Ding = elevator.Ding
	local floorPositions = {}
	for i, floor in ipairs(floors) do
		floorPositions[i] = floor
	end
	local floorQueue = {}
	local moving = false
	local direccion = nil
	local currentFloor = 1

	local function abrirCerrarPuertas(floorNumber)
		local pisoFolder = elevator.Parent.Parent.Elevador.PuertasElevador
		local piso = pisoFolder:FindFirstChild("Piso" .. tostring(floorNumber))
		if not piso then return end
		local puertaPiso1 = piso:FindFirstChild("Piso" .. floorNumber .. ".1")
		local puertaPiso2 = piso:FindFirstChild("Piso" .. floorNumber .. ".2")
		local puertaAsc1 = elevator.Parent.Parent:FindFirstChild("Puerta1")
		local puertaAsc2 = elevator.Parent.Parent:FindFirstChild("Puerta2")
		local function moverPuerta(puerta, offset)
			local newCFrame = puerta.CFrame * CFrame.new(0,0,offset)
			local tween = TweenServicePlus:Construct(puerta, TweenInfo.new(1), {CFrame = newCFrame})
			tween:Play()
			return tween
		end
		puertaAsc1.Anchored = true
		puertaAsc2.Anchored = true
		puertaAsc1.WeldConstraint.Enabled = false
		puertaAsc2.WeldConstraint.Enabled = false
		local t1 = moverPuerta(puertaPiso1, -3.5)
		local t2 = moverPuerta(puertaPiso2, 3.5)
		local t3 = moverPuerta(puertaAsc1, 3.5)
		local t4 = moverPuerta(puertaAsc2, -3.5)
		t4.Completed:Wait()
		wait(2)
		local c1 = moverPuerta(puertaPiso1, 3.5)
		local c2 = moverPuerta(puertaPiso2, -3.5)
		local c3 = moverPuerta(puertaAsc1, -3.5)
		local c4 = moverPuerta(puertaAsc2, 3.5)
		c4.Completed:Wait()
		puertaAsc1.Anchored = false
		puertaAsc2.Anchored = false
		puertaAsc1.WeldConstraint.Enabled = true
		puertaAsc2.WeldConstraint.Enabled = true
	end


	local function updateQueue()
		if direccion == "up" then
			table.sort(floorQueue, function(a, b) return a < b end)
		elseif direccion == "down" then
			table.sort(floorQueue, function(a, b) return a > b end)
		end
	end
	
	local function requestFloor(floorNumber)
		for _, f in ipairs(floorQueue) do
			if f == floorNumber then return end
		end
		table.insert(floorQueue, floorNumber)
		updateQueue()
	end

	local function moveToFloor(floorNumber)
		moving = true
		if currentFloor == floorNumber then
			task.wait(0.5)
			abrirCerrarPuertas(currentFloor)
			moving = false
		else
			local targetPos = floorPositions[floorNumber]
			direccion = (floorNumber > currentFloor) and "up" or "down"
			local tween = TweenServicePlus:Construct(elevator, TweenInfo.new(10, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut), {CFrame = targetPos.CFrame})
			tween:Play()
			tween.Completed:Wait()
			currentFloor = floorNumber
			Ding:Play()
			abrirCerrarPuertas(floorNumber)
			moving = false
		end
	end

	for _,boton in elevator.Parent.Parent.Elevador.BotonesElevador:GetChildren() do
		local floorNumber = tonumber(boton.Name)
		local color = Color3.fromRGB(165,115,115)
		boton.ClickDetector.MouseClick:Connect(function()
			boton.Color = Color3.fromRGB(165,146,146)
			if floorQueue[floorNumber] then return end
			requestFloor(floorNumber)
			task.wait(1)
			boton.Color = color
		end)
	end

	while true do
		wait(0.5)
		if not moving and #floorQueue > 0 then
			local nextFloor = table.remove(floorQueue, 1)
			moveToFloor(nextFloor)
		end
	end
end

return ElevatorModule
1 Like

Alright, the way I see it, there’s two ways to fix this. But I will first discuss why your character “phases” through the floor of the elevator.

The main reason that I can think of is because of how Roblox deals the physics between the elevator floor part and the character’s root part. From my end where I have scripted a simple elevator script using the public module you have used (TweenServicePlus), I find it that when the player character goes onto the anchored elevator part and the elevator part goes up via a tween, Roblox’s physics engine does not register the moving elevator part as being involved with physics (because the part is moving via a tween, not a force), so your character model seems to phase through the floor as you go up.

The effect of this “phasing” depends on the speed at which the elevator part is travelling. If it is slow then it can be negligible, but if it’s going very fast then the effect is visible and, like you said, might make the character model fall through the part.

The first solution I can think of is to set a fixed speed at which the elevator can go. You’re gonna have to test out different speed values until you can dismiss the “phasing” effect. With this, you can calculate the time the tween needs to complete by dividing the distance between the target and current floor by the fixed speed value.

The second solution, which is identical to your method, is to weld the elevator part to the character’s root part. This is the simplest and easiest method, but your character’s model animation while the elevator moves will appear as if it is falling. The only way I can think of to remove this animation is to force play the character’s idle animation while the elevator moves and resume back all of the animations once the elevator stops.

1 Like

i tried the second solution, and i found more problems than solutions, so i will try the first solution you mention, any idea on how to do it in-game?

Define the “problems” you have encountered.

I have already explained it in my previous post. Please re-read it again. You can quote any part of my previous post that seems confusing to you and I will do my best to clarify it.

it was mostly logic problems trying to adapt the Welding outside of the elevator, making the player not weird bcs i was using the PlatformSteped value on the humanoid to preventing it from making the fall animation while using RunService, probably it was my fault

im not really good with english so i can’t really tell what i couldn’t read properly, but wym “fixed speed”(ik you mean a speed that doesn’t change, i mean what could yo mean “fixed speed” inside the script) also i want to know how to put the calculation in the script, i didn’t really understanded how to make that

I don’t get what you mean by this.

Fixed speed means a value that you set in your script that represents the speed at which your elevator moves. You set up a constant variable that contains a number which represents the elevator’s part speed when it is moving.
Because different floors require different times to reach depending on which floor you are currently at, you need to manually calculate the time needed to go from one floor to the other by using a formula. You can calculate the time needed to reach a certain floor using the following formula:

Speed / Distance

Speed would be the constant variable you have set up, whereas distance would be a number that represents how far is between the floor the player is currently on and the floor the player wishes to go to.