Rotating part shift overtime when rotating?

I have a model with two parts, one of the parts called part2 rotates 90 degrees relative to the other part. this works when anchored but when I unanchor them part2 will begin to shift away and this is a problem.

local pos = script.Parent.Part2.Position - script.Parent.Part.Position

local weld = Instance.new("WeldConstraint")
script.Parent.Part2:BreakJoints()
script.Parent.Part:BreakJoints()
weld.Parent = script.Parent.Part2
weld.Part0 = script.Parent.Part2
weld.Part1 = script.Parent.Part



while true do
	wait(0.5)
	print("removing part1")
	weld.Part1 = nil
	print("setting part2 cframe")
	script.Parent.Part2.CFrame = script.Parent.Part2.CFrame * CFrame.Angles(0,0,math.rad(90))
	print("setting part1")
	weld.Part1 = script.Parent.Part
	print("resetting position")
script.Parent.Part2.Position = script.Parent.Part.Position + pos
end

a weld is made and when part2 needs to rotate, the weld is disconnected briefly so that the CFrame of part2 can be set, then the weld is connected again, and it attempts to place part2 back to were it was before rotating.
instead it slowly drifts away instead of being placed back to were it was originally.
how can I fix this?

Is there a way that you will be able to give us a picture/video?

The code seemed to work for me.

did you have it anchored? have this script run while the whole model is moving around.

I tested with both parts anchored/un-anchored - still worked without moving the main part.

sorry for the wait, had to convert the file to mp4

you can see the purple part shift slightly when the script runs.

It seems like a collision issue, are the parts cancollide false?

they are all cancollide true. but they shouldnt be colliding with each other as they were dragged together in the studio.

I just read up on WeldConstraints (as I do not use them), and the reason the part may keep moving for you is because you are changing its CFrame, which has a different effect than its position.
I re-adjusted the code for you:

local pos = script.Parent.Part2.Position - script.Parent.Part.Position

local weld = Instance.new("WeldConstraint")

script.Parent.Part2:BreakJoints()

script.Parent.Part:BreakJoints()

weld.Parent = script.Parent.Part2

weld.Part0 = script.Parent.Part2

weld.Part1 = script.Parent.Part

while true do

wait(0.5)
 --- I removed the "weld.part1 = nil" as it was unnecessary.
print("setting part2 cframe")

workspace.Model.Part2.Position = workspace.Model.Part2.Position

workspace.Model.Part2.Orientation = workspace.Model.Part2.Orientation + Vector3.new(0, 0, 90)

print("resetting position")

script.Parent.Part2.Position = script.Parent.Part.Position + pos

end

Also, like @VegetationBush said, it also involves the collisions.

If you make part2 non-cancollidable, and massless, it should work. I just tested it.

That explains it, try setting the cancollide to false to see if that does anything

so…yes, it does work, but, the rotating part doesnt seem to move parts along with it.
forgive me if I forgot to mention this as I thought it wasnt necessary. but part2 must be doing two things:

when part2 rotates, any parts attached to it that are not part1, should rotate with it.
because of the nature of the game, forces are expected to be applied to part2, so part2 must be able to compensate by remaining in a specific position relative to part1’s position.

the example model made in this post was a test in an attempt to fix the shifting issue.

EDIT: I see everyone left on me, guess I should just mark as solution then. :confused:

Sorry, was doing homework.

I’d need more information about the:

portion. Are they welded together? Are they surfacejoined?

its fine, I believe I found the solution:

local pos = script.Parent.Part2.Position - script.Parent.Part.Position

local weld = Instance.new("WeldConstraint")

script.Parent.Part2:BreakJoints()

script.Parent.Part:BreakJoints()

weld.Parent = script.Parent.Part2

weld.Part0 = script.Parent.Part2

weld.Part1 = script.Parent.Part

local current = script.Parent.Part.CFrame:ToObjectSpace(script.Parent.Part2.CFrame)



local mode = false




while true do

wait(0.5)

weld.Part1 = nil

if mode == false then
script.Parent.Part2.CFrame = script.Parent.Part.CFrame:ToWorldSpace(current) * CFrame.Angles(0,0,math.rad(90))
mode = true
elseif mode == true then
	script.Parent.Part2.CFrame = script.Parent.Part.CFrame:ToWorldSpace(current)
	mode = false
end


weld.Part1 = script.Parent.Part


end

it does move very slightly sometimes but it doesnt continue to drift and will correct itself overtime. I needed to use ToWorld/ToObject space to keep it relative to the other part.

1 Like