Cframe increment script? (position)

Hello, Scripting Support. I once again request your help. I am trying to figure out the a script that increases/decreases the cframe lets say 0.1 each second also i want it start the increment on a specific position which lets assume is (0, 0, -54.969), i want the script in such a way that each second it goes (0, 0, -54.869) and so on until i want it to stop I have not found a solution on the forums, so I decided to ask directly.

2 Likes

You are able to lerp CFrames like so:

local start = CFrame.new(0, 0, -54.969)
local goal = CFrame.new(0, 0, -54.869)
local v = 0
local connection

local print = print

connection = game["Run Service"].PostSimulation:Connect(function(deltaTime)
   v += deltaTime

   print(start:Lerp(goal, v))
end)

Checking the output will see that after 1 second (depends on your device due to the nature of deltaTime), the result will reach your target. You can then disconnect the loop once the target is reached. The deltaTime’s unit is seconds so if you do: deltaTime / 2, it will take 2 seconds to reach the goal CFrame

Quick edit: if you want to stop v at 1 exactly you can use: v = math.min(v + deltaTime, 1) instead of: v += deltaTime

4 Likes

okay so i tried this but it does not seem to change the cframe in game , im using this script inside the attachment , or does this script work only for parts?

1 Like

their are no errors in the console , it just prints the Cframe increment but the Attachment does not actually change positions in game

1 Like

yeah i checked the workspace and the position is not changing image

2 Likes

I believe all you need to do is create a loop to continuously add to the CFrame, such as the following:

local testCFrame = CFrame.new(0, 0, 5)

while true do
  --0.1 is how much you want to increment the z coordinate by
  testCFrame += Vector3.new(0, 0, 0.1)

  wait(1)
end

If you want it to smoothly transition every second instead of a sudden jump, you could do the following to modify the position every frame instead of every second, but at the same rate:

local testCFrame = CFrame.new(0, 0, 5)

while true do
  local deltaTime = game:GetService("RunService").Heartbeat:Wait()

  testCFrame += Vector3.new(0, 0, deltaTime * 0.1)
end

The reason I multiplied deltaTime by 0.1 in the second example was because (0.1studs / 1second) is 0.1, which is the factor between the two.

This is the result (The red one moves every frame and the blue one moves every second).
Move.wmv (685.1 KB)

If you’re looking for how to interpolate it between two points then @JohhnyLegoKing is correct I believe.

2 Likes

I didn’t know you needed the script to move attachments. Attachments have both a CFrame and a WorldCFrame property. The WorldCFrame moves the attachment relative to the world’s origin, and the CFrame property moves it relative to the parent object’s position. If you want to move the attachment relative to the world, changing: print(start:Lerp(goal, v)) to: attachment.WorldCFrame = start:Lerp(goal, v) should work

3 Likes

This is how I tested it by the way

local part = workspace:WaitForChild("Part");

spawn(function()
	while true do
		--0.1 is how much you want to increment the z coordinate by
		part.CFrame += Vector3.new(0, 0, 0.1)
		wait(1)
	end
end)

local part1 = workspace:WaitForChild("Part1");

while true do
	local deltaTime = game:GetService("RunService").RenderStepped:Wait()

	part1.CFrame += Vector3.new(0, 0, deltaTime * 0.1)
end
2 Likes

Thats pretty cool , do i have to change anything for it to work on attachments? my bad i should have mentioned on the question that i need it for Cframe attachment and not parts

1 Like

I’m fairly sure that to adjust it for attachments all you would need to do is replace part.CFrame with attachment.WorldCFrame like how JohhnyLegoKing said, although I think it’s more conventional to use RenderStepped or Heartbeat instead of spawn with a while loop:

game:GetService("RunService").RenderStepped:Connect(function(deltaTime)
  attachment.WorldCFrame += Vector3.new(0, 0, deltaTime * 0.1)
end
3 Likes

thank you so much worked perfectly

2 Likes

this works perfectly for the increment i just dont know how to stop the increment at a specific Cframe position , could u help me with that?

local nyc = game.Workspace:WaitForChild("nycbeam")
local attachment = nyc:WaitForChild("Attachment2")

while true do
	local deltaTime = game:GetService("RunService").Heartbeat:Wait()

	attachment.WorldCFrame += Vector3.new(0, 0, deltaTime * 0.1)
end
1 Like

oh and lets say i want to end the increment at position ( 0, 0, -48.989 ) , after it reaches that end position i would want it go back at the beginning and start the increment, basically looping it

1 Like

If you want to stop it at a specific CFrame position, you can calculate where it’s going to be the next frame, and if it’s going too far, reset it to initial position. In this specific example I can just compare the Z values, but in the future where it may not be perfectly aligned with the Z axis, you would compare the magnitude between the initial and final position, or see if the object is going to be further or closer to it’s final position (and if it’s going further the next frame reset it), or something similar to that.

local nyc = game.Workspace:WaitForChild("nycbeam")
local attachment = nyc:WaitForChild("Attachment2")
local initialPosition = attachment.WorldPosition
local limit = Vector3.new(0,0,-48.989)

while true do
	local deltaTime = game:GetService("RunService").Heartbeat:Wait()
	local increment = Vector3.new(0, 0, deltaTime * 0.1)
	if (attachment.WorldCFrame + increment).Z >= limit.Z then
		attachment.WorldPosition = initialPosition
		continue
	end
	attachment.WorldCFrame += increment
end

In this example, if the attachment’s Z coordinate is initially less than -48.989, you would check if it’s bigger than or equal to the next frame like I did. If it’s going the other direction, you would compare using this: <= instead of this >=

1 Like

tried it and it keeps going and does not stop the increment at the limit cframe value… any fixes?

Sorry to bother u but i was thinking hard and found an easier way to do that, i can just use a wait(10) so it reaches the position and then manually apply the Cframe position of the start to the attachment doing this attachment.CFrame = CFrame.new(0,0,-48.989)

1 Like

nevermind what i thought it dint work , i dont know what im doing wrong in here but the attachment just does not increment

local nyc = game.Workspace.roofbeams:WaitForChild("nycbeam")
local attachment = nyc:WaitForChild("Attachment2")
while true do
        local deltaTime = game:GetService("RunService").Heartbeat:Wait()
	attachment.WorldCFrame += Vector3.new(0, 0, deltaTime * 0.1)
	task.wait(20)
	attachment.CFrame = CFrame.new(0, 0, -78.758)
end

@DaBagelBoy any help regarding the code i sent above? As soon as i remove the task.wait and the attachment.Cframe line , the code works fine but i still dont know how to stop the increment

Just to clear things up, you’re asking how to get it to reset after 20 seconds or so? If that’s the case, then the code that you’re using will move the attachment by one frame, wait 20 seconds, and then reset the position in an endless loop. You could either keep track of the elapsed time and reset it if it’s been surpassed, or you could create a coroutine that counts how much time has passed to reset the attachment. This is the result I got with the elapsed time method, where I had to wait 5 seconds for it to reset:

local attachment = Instance.new("Attachment", workspace.Terrain)
attachment.WorldPosition = Vector3.yAxis
attachment.Visible = true

local elapse = 0
local timeLimit = 5

local initialPosition = attachment.WorldPosition

while true do
	if (elapse >= timeLimit) then
		attachment.WorldPosition = initialPosition
		elapse = 0
	end
	
	local deltaTime = game:GetService("RunService").Heartbeat:Wait()
	
	attachment.WorldCFrame += Vector3.new(0, 0, deltaTime * 0.1)
	elapse += deltaTime
end

For your use case you would set the timeLimit to 20

1 Like

yes thank you thats perfectly what i wanted but something is glitchy in it which makes my attachment a completely different CFrame , i want it to increment from the orginal position of the CFrame but ur script makes it have a new CFrame and increment from there when i play the game