How to make moving cloud actually move the players?

local TweenService = game:GetService("TweenService")

local OriginCloudStarter = script.Parent
local CloudPlatform = OriginCloudStarter:WaitForChild("CloudPlatform")

local function CloudTweenV1()
	local CloudTween = TweenService:Create(CloudPlatform, TweenInfo.new(3, Enum.EasingStyle.Sine), {CFrame = CFrame.new(CloudPlatform.Position - Vector3.new(34, 0, 0))})
	CloudTween:Play()
	CloudTween.Completed:Wait()
	task.wait(3)
	
	local ReturnTween = TweenService:Create(CloudPlatform, TweenInfo.new(3, Enum.EasingStyle.Sine), {CFrame = CFrame.new(CloudPlatform.Position + Vector3.new(34, 0, 0))})
	ReturnTween:Play()
	ReturnTween.Completed:Wait()
	task.wait(3)
end

local function CloudTweenV2()
	local CloudTween = TweenService:Create(CloudPlatform, TweenInfo.new(3, Enum.EasingStyle.Sine), {CFrame = CFrame.new(CloudPlatform.Position + Vector3.new(34, 0, 0))})
	CloudTween:Play()
	CloudTween.Completed:Wait()
	task.wait(3)

	local ReturnTween = TweenService:Create(CloudPlatform, TweenInfo.new(3, Enum.EasingStyle.Sine), {CFrame = CFrame.new(CloudPlatform.Position - Vector3.new(34, 0, 0))})
	ReturnTween:Play()
	ReturnTween.Completed:Wait()
	task.wait(3)
end

local function CloudTweenV3()
	local CloudTween = TweenService:Create(CloudPlatform, TweenInfo.new(3, Enum.EasingStyle.Sine), {CFrame = CFrame.new(CloudPlatform.Position + Vector3.new(0, 34, 0))})
	CloudTween:Play()
	CloudTween.Completed:Wait()
	task.wait(3)

	local ReturnTween = TweenService:Create(CloudPlatform, TweenInfo.new(3, Enum.EasingStyle.Sine), {CFrame = CFrame.new(CloudPlatform.Position - Vector3.new(0, 34, 0))})
	ReturnTween:Play()
	ReturnTween.Completed:Wait()
	task.wait(3)
end

local CloudTweens = {CloudTweenV1, CloudTweenV2, CloudTweenV3}

while true do
	CloudTweens[math.random(1, #CloudTweens)]()
end

I made this code using Tween Service to move the cloud model’s position in a random order (left, right, and up) by 34 units. The code does work correctly but I don’t know why it doesn’t move the player along with it? Can someone explain how to make the moving cloud move the player?

3 Likes

I would recommend looking at this post, seems like it is exactly what you are attempting to accomplish:

I read the code but I don’t understand it. It looks a lot more advanced beyond my understanding O_O

There are comments in the code, but I’ll explain to you the important parts(I did make a few improvements, but they are pretty small):

SETUP:

local Char = script.Parent
local RootPart = Char:WaitForChild("Head")
local LastTrainCFrame, Connection

local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Exclude
Params.FilterDescendantsInstances = {Char}
local stickyParts = {
	CloudPlatform = true,
	--AnotherName = true,
}

Makle the variables we need

DETECTION:

game:GetService('RunService').Heartbeat:Connect(function()
	local result = workspace:Raycast(RootPart.Position, -Vector3.yAxis*50, Params)
	local target = result and result.Instance
	
	if target and stickyParts[target.Name] then

Every frame, Shoot a ray 50 studs down from our head and see what is beneath us. If we are standing on something in our list, then we have some more code to run.

MOVEMENT:

		local TrainCF = target.CFrame 
		if LastTrainCFrame == nil then -- If no LastTrainCFrame exists, make one!
			LastTrainCFrame = TrainCF  -- This is updated later.
		end
		local Rel = TrainCF * LastTrainCFrame:inverse()
		
		LastTrainCFrame = TrainCF  -- Updated here.
		RootPart.CFrame = Rel * RootPart.CFrame -- Set the player's CFrame
	else
		LastTrainCFrame = nil -- Clear the value when the player gets off.
	end
end)

See how much the train has moved since our last recorded position, and apply that to our character

Make a LocalScript placed inside StarterPlayer > StarterCharacterScripts

Full Code
local Char = script.Parent
local RootPart = Char:WaitForChild("Head")
local LastTrainCFrame, Connection

local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Exclude
Params.FilterDescendantsInstances = {Char}
local stickyParts = {
	CloudPlatform = true,
	--AnotherName = true,
}

game:GetService('RunService').Heartbeat:Connect(function()
	local result = workspace:Raycast(RootPart.Position, -Vector3.yAxis*50, Params)
	local target = result and result.Instance
	
	if target and stickyParts[target.Name] then
		local TrainCF = target.CFrame 
		if LastTrainCFrame == nil then -- If no LastTrainCFrame exists, make one!
			LastTrainCFrame = TrainCF  -- This is updated later.
		end
		local Rel = TrainCF * LastTrainCFrame:inverse()
		
		LastTrainCFrame = TrainCF  -- Updated here.
		RootPart.CFrame = Rel * RootPart.CFrame -- Set the player's CFrame
	else
		LastTrainCFrame = nil -- Clear the value when the player gets off.
	end
end)

Is your cloud model just the Anchored part you are tweening?

Tweening a platform should move the player on it if the platform (cloud) is unanchored and welded to the tweened Part.

Players won’t move on a CFramed platform unless you weld them to it like the post that @RoloTheDevBunny linked.

When you weld two parts, they become an assembly, and if one is anchored, the other won’t have physics acting upon it. If you wanted the platform to be affected by physics and follow an anchored part, an AlignPosition/AlignOrientation duo would be best. I would still recommend the code above, though, as it gives a lot more flexibility and can easily apply to any part.

Yeah, it does have a welded part.

The cloud platform that I got from the toolbox didn’t have a platform for the player to stand or move one so I had to make one and weld it together.

Did my solution up above work out for you?

I didn’t test it yet but I’m worried that it may cause a memory leak due to RunService.Heartbeat always running

Memory leaks are caused by not removing conenctions, I said to place the script inside StarterCharacterScripts. When you die, the script is stopped, and all connections are removed.

Oh okay. I get it now. I’ll go test the script :smiley:

Thank You! The script works! :smiley:

1 Like