TweenService Is setting my part's Position wrong!

Hello!

Yes. I’m back after many months with another problem.

So I have a keycard door that uses TweenService (Credit to TheDevKing)

The problem is, everytime it accepts the keycard and tries to open the door it puts it (probally) at 0,0,0.

Code (Normal Script)
local OpenTweenVector3 = Vector3.new(-13.5, 3.65, -268.552)
local CloseTweenVector3 = Vector3.new(-13.5, 3.65, -272.152)
local TweenService = game:GetService("TweenService")
local Part = script.Parent.Parent.Parent.Door
local Delayed = false

script.Parent.Touched:Connect(function(hit)
	if hit.Parent.Name == "EnginnerKeycard" and Delayed == false then
		Delayed = true
		print("Delayed is set to true")
		script.Parent.Parent.Color.BrickColor = BrickColor.new("Bright green")
		script.Parent.Parent.Parent.KeycardReader2.Color.BrickColor = BrickColor.new("Black")
		script.Parent.Parent.Parent.KeycardReader2.Sensor.Script.Disabled = true
		script.OpenTween.Position.Value = OpenTweenVector3
		script.CloseTween.Position.Value = CloseTweenVector3
		require(script.OpenTween)
		wait(3)
		require(script.CloseTween)
		script.Parent.Parent.Color.BrickColor = BrickColor.new("Bright red")
		wait(1.5)
		Delayed = false
		print("Delayed is set to false")
		script.Parent.Parent.Parent.KeycardReader2.Color.BrickColor = BrickColor.new("Bright red")
		script.Parent.Parent.Parent.KeycardReader2.Sensor.Script.Disabled = false
		script.OpenTween:Remove()
		script.CloseTween:Remove()
		game.ReplicatedStorage.TweensSingleDoor.OpenTween:Clone().Parent = script
		game.ReplicatedStorage.TweensSingleDoor.CloseTween:Clone().Parent = script
		wait(0.095)
		script.OpenTween.Position.Value = OpenTweenVector3
		script.CloseTween.Position.Value = CloseTweenVector3
	end
end)
I forgot to put the ModuleScript
local OpenTween = {}
local TweenService = game:GetService("TweenService")
local Part = script.Parent.Parent.Parent.Parent.Door

local Info = TweenInfo.new(
	1.5,
	Enum.EasingStyle.Linear,
	Enum.EasingDirection.Out,
	0,
	false,
	0
)

local Goals = 
	{
		Position = Vector3.new(script.Position);
	}

local Tween = TweenService:Create(Part, Info, Goals)

Tween:Play()

return OpenTween

Here’s a video to:


You can tell that the door is moved by looking at the reflection

You’ve some very bad code in this example, I won’t lie.
image
This is definitely not the way to do it as you’re continuing to require which isn’t good.
You need to be moving the door via it’s CFrame and not it’s position.

On the module script, I realized that it said “script.Position”.

That could be the issue.

Oh yea I forgot to mention that there’s a Vector3Value in the ModuleScript.

@LordMerc And? It’s like saying someone’s code is bad when they just begun scripting 2 months ago.

Your issue is identical to one I solved. Have a look at the solution and see if it helps:

1 Like

Alright, try doing this to the module.

local mainmodule = {}

mainmodule.Tween = function(part, position)
    
    local tweenservice = game:GetService("TweenService")
    
    local tweeninfo = TweenInfo.new(1)
    
    local goal = {position = position}
    
    local tween = tweenservice:Create(part, tweeninfo, goal)
    
    tween:Play()
    
end

return mainmodule;

for the normal script, put the require as a local variable. Then, call the function with the part and position listed.

You could also try using CFrame value.

And? It’s like saying someone’s code is bad when they just begun scripting 2 months ago.

Try adding some space (empty lines) around your color changing code and adding comments to make it easier to read.

Don’t abusively use require like you are. Module scripts are used to return things to improve code reuse, like “class” objects or functions, not to execute code. Clearly, what you really want is a function to automatically make a fire tweens for you.

Something like this:
local TweenService = game:GetService("TweenService")
local door = script.Parent.Parent.Parent.Door

function makeTween(pos) 
    return TweenService:Create(
        door,
        TweenInfo.new(1.5, Enum.EasingStyle.Linear),
        { Position = pos }
    )
end

local oldpos = door.Position
-- Relative positioning makes your code more easier to reason about
local t = makeTween(door.Position - Vector3.new(0, 0, -3.6))
t:Play()
-- Here, we are waiting for the tween to end instead of waiting the 1.5 seconds 
-- to make our intentions more clear.
t.Completed:Wait()
-- wait() is deprecated, use task.wait() instead
task.wait(1.5) -- Leave the door open for 1.5 seconds
t = makeTween(oldpos)
t:Play()

When you instance a new TweenInfo, you fill in parameters that are already defined as default, which also makes it harder to read.

Use task.wait(), not wait()

Instead of defining absolute positions for your tween goals, defined positions based on where the door is/was. This makes your code easier to edit and reason about.

Changing Delayed to debounce will also make that variable’s purpose easier to understand.

I forgot to mention this, but it seems like you have many doors that each need their own keycard. It may make sense to instead use the CollectionService and attributes to have one script that handles all of the doors, instead of cloning multiple scripts, and then needing to change them all if you want to adjust something.


Oh yea I forgot to mention that there’s a Vector3Value in the ModuleScript .

Maybe change it to script.Position.Value instead?