How can I move a player on a tweened object?

Alright, so I’m trying to create a Celeste thing in roblox, and Celeste has blocks called Traffic Light Blocks. These traffic light blocks light up, move with the player on it, then launches them off. However, I can’t get the “stand on and move with it” part to work.
This is what’s happening:
https://gyazo.com/4336c974c847f45a925ea7f457f2905d

This is what SHOULD be happening:
https://gyazo.com/ba84040f7d607219f0174df098ad2e1a

I can’t put any BodyVelocity/BodyPositions on it because otherwise the movement wont look like it should.

Some solutions I’ve tried was:

and

However both are either buggy or don’t work.
Any help, please? Thanks.

Potentially try welding the player to the platform and when the player requests to jump or move destroy the weld?

You can try to use bodyforces instead?

This sounds promising, I’ll try it!

Dashing is built on bodyforces, so I fear if I did it might interfere

Didn’t work… Are there any other solutions? Or at least a more optimized way to get this?

Well i think i actually i found a way to do it with tweening.

llocal Tween = game:GetService("TweenService")
local Part = workspace.Part

local PartAtt = Part:FindFirstChildWhichIsA("Attachment") or Instance.new("Attachment",Part)
local VC = Instance.new("VectorForce",Part)
VC.RelativeTo = Enum.ActuatorRelativeTo.World
VC.Attachment0 = PartAtt
VC.Force = Vector3.new(0,workspace.Gravity * Part:GetMass(),0)

local AP = Instance.new("AlignPosition",Part)
AP.Attachment0 = PartAtt
AP.MaxForce = math.huge
AP.Mode = Enum.PositionAlignmentMode.OneAttachment
AP.Responsiveness = 3
AP.Position = Part.Position
AP.Enabled = false
AP.Enabled = true

local AO = Instance.new("AlignOrientation",Part)
AO.Attachment0 = PartAtt
AO.Mode = Enum.OrientationAlignmentMode.OneAttachment
AO.MaxTorque = math.huge
AO.CFrame = Part.CFrame
AO.Enabled = false
AO.Enabled = true

local TweenStart = Tween:Create(AP,TweenInfo.new(2,Enum.EasingStyle.Back),{Position = Part.Position + Vector3.new(30,0,0)})
local TweenEnd = Tween:Create(AP,TweenInfo.new(2,Enum.EasingStyle.Back),{Position = Part.Position + Vector3.new(-30,0,0)})

while true do
	TweenStart:Play()
	TweenStart.Completed:Wait()
	wait(2)
	TweenEnd:Play()
	TweenEnd.Completed:Wait()
	wait(2)
end


i just use AligingPosition which Position is being tweened

I just tried it and for me tweenservice also moves the player physically, this is odd.

How could I apply this to a model? I know it has to do with CFrames but attachments are mainly based on vectors if I believe, but I could be wrong.

Did you try my suggestion in the post you linked? Tweened Parts aren’t moved physically, they are ‘teleported incrementally’ so that’s why players will slide off them.
If you use a PrismaticConstriaint to move the Platform the player will stay on it. You’d have to script the “then launches them off” procedure though.

2 Likes

I didn’t use it because I didn’t know if I could change the easing. Can I? If I can, I’ll try it out.

1 Like

Check out LinearResponsiveness.

It’ll work great, but can I subject it to a specific location?

I use this script sometimes created by @nooneisback

Anyways. Make a folder full of the moving parts and put the folders place in Whitelist

-- Localscript inside of StarterCharacterScripts

local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')

local LastHit
local LastTrainCFrame

local Function
local Function2

local Whitelist = {workspace.Trains}

Function = RunService.Heartbeat:Connect(function()
	local RootPart = player.Character.HumanoidRootPart
	local Ignore = player.Character
	local ray = Ray.new(RootPart.CFrame.p, Vector3.new(0,-500,0))
	local Hit, Position, Normal, Material
	if LastHit then
		Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,{LastHit})
		if not Hit then
			Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
		end
	else
		Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,Whitelist)
	end
	if Hit then
		local Train = Hit
		if not LastTrainCFrame then
			LastTrainCFrame = Train.CFrame
		end
		local TrainCF
		if Train ~= LastHit and LastHit then
			TrainCF = LastHit.CFrame
		else
			TrainCF = Train.CFrame
		end
		local Rel = TrainCF * LastTrainCFrame:inverse()
		LastTrainCFrame = Train.CFrame
		RootPart.CFrame = Rel * RootPart.CFrame
		LastHit = Train
		if Train ~= LastHit then
			LastTrainCFrame = Train.CFrame
		end
	else
		LastTrainCFrame = nil
	end
	
	if not Function2 then
		Function2 = player.Character.Humanoid.Died:Connect(function()
			Function:Disconnect()
			Function2:Disconnect()
		end)
	end
end)

I said in the original post that this method is buggy. This seems to work more effectively, but I’m still experiencing the same bugs. I forgot to mention in the original post, however, that the player glitches out in weird ways during testing. The result is this:


Is there any way to fix this?

This question has been asked many times. You can try the optimized solution from this thread:

Works, but the optimized solution kinda slides me and is a little bit buggy.

All right, I guess you should try the original solution then. I just thought the optimized one might work with the new API’s better. Then again, I didn’t really test it. Also, nice side scroller and jump effect.

I’m still experiencing the same stuff in the video I sent. I think it needs to index faster to compensate for the very fast speed of the traffic light blocks. (The speed of the traffic light blocks is 0.719 seconds, then it takes about 2.125 seconds for it to go back to original position)

Use roblox’s physics, instead of setting the CFrame constantly. It is more reliable to make the part use roblox’s physics engine instead of setting the parts CFrame.

1 Like