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?
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)
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.
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.