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.
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
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?
their are no errors in the console , it just prints the Cframe increment but the Attachment does not actually change positions in game
yeah i checked the workspace and the position is not changing
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.
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
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
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
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
thank you so much worked perfectly
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
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
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 >=
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)
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
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