Setting position of part mysteriously causes part to teleport and generate velocity

Currently I’m trying to script a button to open and close whichever wall object it is attached to. The idea is that you press the button, the wall goes up. Press it again, the wall goes down. This behaviour does work, however this is with the caveat that once the player is within a certain distance of the wall, it will just start to follow the player. This only happens once the wall has been activated, and once the player leaves this range, the wall no longer attempts to follow the player. I have truly no idea why it is doing this.

Interact.Button in InteractibleFuncs ModuleScript

function Interact.Button(Object) -- Handles button de/activation
	local Target = Object:FindFirstChildOfClass("ObjectValue").Value
	local Activated = Target:FindFirstChildOfClass("BoolValue") -- Indicates activation state
	
	if Target.Name == "Wall" then		
		if Activated.Value then -- Lowers wall
			Target:TranslateBy(Vector3.new(0, -10, 0))
			Activated.Value = false
		else -- Raises wall
			Target:TranslateBy(Vector3.new(0, 10, 0))
			Activated.Value = true
		end
	end
end

Button Interfacing in InteractionController LocalScript

local Global = require(script.Parent.GlobalFuncs)
local Interact = require(script.Parent.InteractibleFuncs)

Global.Mouse.Button1Down:Connect(function()
	local Cast         = Global.CastToMouse()
	local CastInstance = Cast.Instance
	local CastPosition = Cast.Position
	local Ancestor     = CastInstance:FindFirstAncestor("Interactibles")

	--[[
		The folder structure is as so: Workspace -> Environment -> Interactibles
		The wall Model is in the Environment folder, the button is in the Interactibles folder
	--]]
		
	if Ancestor then
		local Target = CastInstance:FindFirstAncestorOfClass("Model")
		local TargetPivot = Target:GetPivot()
		
		local TargetPosition = Vector3.new(TargetPivot.X, TargetPivot.Y, TargetPivot.Z)
		local LookVector = CFrame.lookAt(Cast.Position, Global.Root.Position)
		
		Global.Task = Target -- This variable just tells the game which item was clicked on
		Global.MoveTo(TargetPosition + LookVector.LookVector.Unit * 6, false)
		
		if Target.Name == "Button" then
			Interact.Button(Target)
		end
		
		return
	end
	
	Global.Task = nil
	Global.TapTarget.Position = CastPosition
	Global.MoveTo(CastPosition, true)
end)

I’ve used multiple different methods of changing the position of the wall (which to be clear is a Model), including TranslateBy, MoveTo, and and PivotTo. All of them result in the same thing. The button and the object are not directly interfaced with anywhere else in my scripts. I’m not sure if its something I overlooked as a consequence of my inexperience or if something has just gone horribly wrong, but if anyone might know what’s going on I would be so grateful!

can we see the global module script? i feel like the issue is with your move function.

it looks like the wall is being continually updaated either through a runtime event like Heartbeat or via some loop

to debug, just put a print statemement anywhere in the same code block that involves moving the wall. either a code block where you update position or in the code block of the function where you move the wall

Absolutely. Of my global functions these two I feel would be most relevant? Placing comments in the interact function yielded nothing helpful. The object’s pivot property also doesn’t change at all despite being able to see it clearly moving? The server can see this as well.

Function to detect the closest object:

function Global.GetNearestObject() -- Checks for the closest interactible object thats within range
	local InteractionDiameter = workspace:GetPartBoundsInRadius(Global.Root.Position, Radius)
	local LowestNumber = 50
	local Nearest = nil

	for i, Object in pairs(InteractionDiameter) do
		local Group = Object.CollisionGroup
		if Group ~= "DungeonInteractible" then continue end

		local Distance = math.floor((Global.Root.Position - Object.Position).magnitude)
		if Distance < LowestNumber then
			LowestNumber = Distance
			Nearest = Object:FindFirstAncestorOfClass("Model") or Object
		end
	end

	if Nearest then
		return Nearest
	end
end

Global MoveTo function:

local ActiveTrail
function Global.MoveTo(Position) -- Pathfinds the player to the defined location

	ActiveTrail = newproxy()
	local CurrentTrail = ActiveTrail

	local Trail = Global.PathFindingService:CreatePath({
		AgentCanJump = false,
		AgentCanClimb = true,
		AgentHeight = 8,
		AgentRadius = 5
	})

	local Success, Error = pcall(function()
		Trail:ComputeAsync(Global.Root.Position, Position)
	end)

	local Waypoints = Trail:getWaypoints()
	if Success and Trail.Status == Enum.PathStatus.Success then		
		for i, Waypoint in pairs(Waypoints) do
			if ActiveTrail ~= CurrentTrail then Global.Task = nil return end
			if i <= 2 then continue end
			
			Global.Humanoid:MoveTo(Waypoint.Position)
			Global.Humanoid.MoveToFinished:Wait()
		end
	end
end

yeah im almost certain its your MoveTo function. i feel like the issue is with the last forloop. it seems youre moving the wall along a trail

1 Like

The Global player variables are as so:

Global.Player    = game.Players.LocalPlayer
Global.Character = Global.Player.Character or Global.Player.CharacterAdded:wait()
Global.Humanoid  = Global.Character:WaitForChild("Humanoid")

Additionally, I completely gutted the Global MoveTo function from the button press function and, even when I’m moving with WASD, the problem still persists…? Even going so far as to change the position of the underlying Part rather than the Model itself to a hardcoded position causes the same exact thing.

The only functions running each frame are camera controllers and a function to update the Nearest Object every frame. Commenting out these functions does not fix this issue.

Just now realized the object wasn’t anchored, and anchoring it fixes the issue, I guess. I feel like this shouldn’t have been happening regardless but I have my solution and I’m not satisfied with this solution because I don’t know what was causing this in the first place, but if it works for what I need then it works, I suppose. Thank you for your patience, truly.

are you able to point out which code is related to the movement of the wall?

It would be the two code blocks from the original post.

ok so to tesst it out place two print statments

one in the interact.button function

second in the button1down event right above where you call Interact.Button(Target)

run the game and see which one is firing over and over. and sc the ouput

1 Like

Both of them fire once, and nothing fires again when the wall begins to follow the player. With the only thing preventing this being Anchoring the part I genuinely wonder if this is a bug.

definately not a bug with roblox. this is something scripted. there must be something moving the wall. if it isnt a script then something may be parented to the wall that might cause this action.

check the explorer for the waall before you press the button and see if anything is parented under it.

if its a script the only way is to try and comment out line by line to see what causes the movement

if anchoring stops the wall then it could be moving via some physics mechanism.

I’ve observed a few things:

  1. Changing CustomPhysicalProperties seems to do nothing.
  2. Changing the shape of the part exhibits different behaviors:
    2.1. Block and Wedge behaves the same; it snaps down and chases the player.
    2.2. Ball will snap down and then roll away because it’s a ball.
    2.3. Corner Wedge and Cylinder will snap down but then they won’t chase the player at all.

Additionally, I’ve observed that the AssemblyLinearVelocity and the AssemblyAngularVelocity are each 0, 0, 0 when the part loads in, but when the conditions are right to trigger the movement, they become -0.346, 0.087, -0.239 and -0.05, 0, 0.073 respectively. There is nothing in my code that explicitly modifies these properties, so you are probably on track with the strange physics behavior.

The part does not seem to be attached in any way to pathfinding at all though; it moves regardless of if I’m using the Pathfinding API, and if I stand still the part will simply just push me. It does however seem to determine its direction based on which direction the player is going relative to the part. In particular it seems to prioritize the Z axis?

Resetting the part’s velocity back to 0, 0, 0 on Heartbeat however has no effect, so I would reason this force is coming from somewhere else, but I am genuinely at a loss. I have gone as far as to completely comment out every single script I have, including my Camera script, and doing the bare minimum required to just move the part.

wait(1)
game.workspace.Environment.Wall:WaitForChild("Part").Position = game.workspace.Environment.Wall:WaitForChild("OpenPos").Value

Even this isn’t enough. It still happens. I have no idea why. I don’t know if my gravity was misconfigured, but it shouldn’t be. I never touched it. I don’t know if I’m misunderstanding the behavior of changing Position or if perhaps I’m misunderstanding the behavior of BaseParts in general, but the only thing that has worked at all is Anchoring the part.

I want to try and understand why this is happening so I can avoid it in the future, because this is really questionable behavior, but I feel like I’ve hit a wall.

try turning off your characters collision and see how the wall acts.

whats the code that moves the wall? ignore me I just got here

The function takes in the Button instance and proceeds to interact with the Wall instance (which is a model) set in the Button’s ObjectValue. It changes its position by tweening the position of the part within the model. I should note however that this behavior is observed if I change the pivot/CFrame of the model itself, too.

function Interact.Button(Object)
	local Target = Object:FindFirstChildOfClass("ObjectValue").Value
	local Activated = Target:FindFirstChildOfClass("BoolValue")
	
	if Target.Name == "Wall" then
		local Offset, Tween
		
		if Activated.Value then -- Lowers wall
			Offset = Target.ClosePos.Value
			Activated.Value = false
		else -- Raises wall
			Offset = Target.OpenPos.Value
			Activated.Value = true
		end
		
		Global.TweenService:Create(Target.Part, TweenInfo.new(1.2), { Position = Offset }):Play()
	end
end

Interestingly, the wall behaves as it should if I have my player collision off and doesn’t try to follow me.

Is there some code that interacts with unAnchored or collidable Objects? is it due to the collision group?

like if Distance < LowestNumber.

but distance gets floored? idk whats happening for this bug to cause so im just listing random stuff.

that is very interesting. have you tried anchoring the wall as soon as it goes down?

if you need it to be unanchored just anchor it and unanchor it after a few seconds when the player should be well out of the way