CFrame math gone wrong

I want to lerp a part with an attachment, so the attachment stays relative to its original position
But when shrinking the size of the part for long enough, the attachment behaves erratically, and eventually goes off to infinity.
Why is this?

To recreate this, just have a part with an attachment in it with a z position of anything else but 0 (this also works on the x axis, but then you need to change the code to affect the x axis). Finally, the part’s z size needs to be more than 9 (I have it at 10).

local Part=game.Workspace.Part
local Attachment=Part.Attachment
local OldAttachmentPos=CFrame.new()
local LastCF=Vector3.new(0,0,0)

for alpha=0,1,0.003 do
	--GenerateNextPos
	local nextpos=Vector3.new():Lerp(Vector3.new(0,0,-9),alpha)
	
	--PartSize
	Part.Size=nextpos+(Part.Size-LastCF)
	LastCF=nextpos
	
	--AttachmentPosition
	local nextApos=CFrame.new((nextpos.X*Attachment.CFrame.Position.X)/Part.Size.X,
		(nextpos.Y*Attachment.CFrame.Position.Y)/Part.Size.Y,
		(nextpos.Z*Attachment.CFrame.Position.Z)/Part.Size.Z)
	
	print(OldAttachmentPos.Position.Z," ! ",Attachment.CFrame.Position.Z," ! ",nextApos.Position.Z," ! ",OldAttachmentPos:Inverse().Position.Z)
	
	Attachment.CFrame=nextApos*(Attachment.CFrame*OldAttachmentPos:Inverse())
	OldAttachmentPos=nextApos
	

	task.wait()
	task.wait()
end


This may be like a floating point rounding issue, but its so weird just seeing it arise from nothing.


The blue circled points are where the problems first begin, where it starts oscillating back and forth. Above it you can see the position moving down by roughly 0.01, but after it jumps around adding and subtracting (adding a negative) larger and larger numbers until it reaches infinity, then nan.
This is so weird. Especially since the size works normally.
I suspect it has something to do with :Inverse() but I don’t know. Any help appreciated!

Root of the problem still unknown, instead of doing this, I just made a script on every attachment to adjust its position.

local oldsize=script.Parent.Parent.Size
script.Parent.Parent:GetPropertyChangedSignal("Size"):Connect(function()
	local Size=script.Parent.Parent.Size
	local OldPos=script.Parent.CFrame
	local NewPos=CFrame.new((Size.X*OldPos.Position.X)/oldsize.X,
		(Size.Y*OldPos.Position.Y)/oldsize.Y,
		(Size.Z*OldPos.Position.Z)/oldsize.Z
	)
	local finalCFrame=(OldPos-OldPos.Position)*NewPos
	script.Parent.CFrame=finalCFrame
	OldPos=NewPos
	oldsize=Size
end)

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