Did you ever figure this out?
Having similar issues
just wondering, How do you do that?
I’m having similar issues as well. Did he ever respond to you?
Nope, I’m still searching and experimenting as well
If you find anything can you let me know please? I’m browsing through so many posts and trying different things and I’ve yet to find anything
Hey, I took a look at the thread. I looked at what worked best for me. However there were some bugs with the LastPartCFrame not being reset, so I fixed it. Here is the code optimized to work with the new Raycasting method too.
Update: it can also check for HumanoidStateTypes
--[[
SETUP
1. Make a LocalScript
2. Put it inside of StarterCharacterScripts
3. Make a folder in workspace and call it "MovingObjects"
4. Put all your moving objects in that folder
5. OPTIONAL, the CheckStates variable will set the CFrame if the character's HumanoidState is not Jumping and not swimming
]]
--BrahGames 07-27-2021 rewritten https://devforum.roblox.com/t/jailbreak-train-platform-system/236339
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')
local CheckStates = true
local LastPartCFrame
local LastPart
local Function
local Function2
function CFrameLogic(Raycast, CFramePart)
--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION
if Raycast.Instance ~= LastPart then
LastPart = Raycast.Instance
LastPartCFrame = nil
end
local Train = Raycast.Instance
if LastPartCFrame == nil then -- If no LastTrainCFrame exists, make one!
LastPartCFrame = Train.CFrame -- This is updated later.
end
local TrainCF = Train.CFrame
local Rel = TrainCF * LastPartCFrame:inverse()
LastPartCFrame = Train.CFrame -- Updated here.
CFramePart.CFrame = Rel * CFramePart.CFrame -- Set the player's CFrame
--print("set")
end
Function = RunService.Heartbeat:Connect(function()
--------------------------------------------------------------- CHECK PLATFORM BELOW
-- Build a "RaycastParams" object
local MovingObjects = workspace.MovingObjects --Make a folder and put all moving objects into it and call the folder "MovingObjects"
local HumanoidRootPart = player.Character.HumanoidRootPart
local humanoid = player.Character.Humanoid
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.FilterDescendantsInstances = {MovingObjects}
raycastParams.IgnoreWater = true
-- Cast the ray
local Hit = workspace:Raycast(HumanoidRootPart.CFrame.p, Vector3.new(0,-50,0), raycastParams) --Casts a ray facing down
--------------------------------------------------------------------------------------------
if Hit and Hit.Instance:IsDescendantOf(MovingObjects) then -- Check if the ray hits and if it hits an object inside of MovingObjects
if CheckStates then -- check if the character is jumping
if humanoid:GetState() == Enum.HumanoidStateType.RunningNoPhysics or humanoid:GetState() == Enum.HumanoidStateType.Running or humanoid:GetState() == Enum.HumanoidStateType.Landed or humanoid:GetState() == Enum.HumanoidStateType.PlatformStanding or humanoid:GetState() == Enum.HumanoidStateType.Seated or humanoid:GetState() == Enum.HumanoidStateType.GettingUp or humanoid:GetState() == Enum.HumanoidStateType.None or humanoid:GetState() == Enum.HumanoidStateType.Physics or humanoid:GetState() == Enum.HumanoidStateType.Ragdoll or humanoid:GetState() == Enum.HumanoidStateType.Dead then
CFrameLogic(Hit, HumanoidRootPart)
else
LastPartCFrame = nil -- Clear the value when the player gets off.
end
else
CFrameLogic(Hit, HumanoidRootPart)
end
else
LastPartCFrame = nil -- Clear the value when the player gets off.
end
end)
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect() -- Stop memory leaks
Function2:Disconnect() -- Stop memory leaks
end)
Just set the local variable CheckStates to false
But my train i’ll broke if i put it on that folder what can i do in that case?
That would depend on how your train system works.
i changed the Hit.Name to find a value called “Moving” so it would be more customizable
The script doesn’t work when the player dies
Edit : Nvm i just had to put in StarterCharacterScripts
Is there a way to make this work for a model, instead of just a part??
Try welding all the parts in that model together and then placing this script in the part everything is welding. Or you could(I don’t know how well this is for performance) place the script inside every part, this is way is more tedious.
Personally, I would try welding all the other parts together, this may make it easier.
make it detect the parent and see if its name is one it makes a platform
Hey, I have a spinning part and while it does make me stay on a little bit, it’s very jittery and sometimes I get teleported away.
Here is a GIF of me getting on the spinning platform:
https://gyazo.com/29f05fc0cdfffceb730ea64fb3c92b07
Here is my code, the script being located under starterplayerscripts.
local collectionService = game:GetService("CollectionService")
local player = game.Players.LocalPlayer
for _,spinningPart in pairs(collectionService:GetTagged("SpinningPart")) do
local lastSpinningPartCFrame = nil
game:GetService("RunService").RenderStepped:Connect(function()
local speed = 60 / spinningPart.Configuration:GetAttribute("SpinSpeed")
spinningPart.CFrame = spinningPart.CFrame*CFrame.Angles(0,math.pi/speed,0)
end)
game:GetService("RunService").Heartbeat:Connect(function()
local character = player.Character or player.CharacterAdded:Wait()
local root = character.HumanoidRootPart
local r = Ray.new(root.CFrame.p,Vector3.new(0,-3,0))
local hit,position,normal = workspace:FindPartOnRay(r,character)
if hit and hit.Name == "SpinningPart" then
if lastSpinningPartCFrame == nil then
lastSpinningPartCFrame = hit.CFrame
end
local spinCF = hit.CFrame
local Rel = hit.CFrame * lastSpinningPartCFrame:inverse()
root.CFrame = Rel * root.CFrame
print("set")
else
lastSpinningPartCFrame = nil
end
end)
end
I am trying to make a spinning part in my obby that keeps the player on it. It seems to be too big for body position or body angular velocity.
Tried to converting this to use Collectionservice so i can just tag parts and itll work
decided to test on my boat tween test, and the player just spazzes out, any ideas?
Using a boat from Jailbreak to show off what i mean
My Code –
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')
local Tag = game:GetService("CollectionService")
local LastTrainCFrame
local Function
local Function2
Function = RunService.Heartbeat:Connect(function()
--------------------------------------------------------------- CHECK PLATFORM BELOW
local RootPart = player.Character.LowerTorso
local Ignore = player.Character
local ray = Ray.new(RootPart.CFrame.p,Vector3.new(0,-50,0))
local Hit, Position, Normal, Material = workspace:FindPartOnRay(ray,Ignore)
if Hit and Tag:GetTags(Hit,"Surface") then -- Change "RaftTop" to whatever the moving part's name is
--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION
local Train = Hit
if LastTrainCFrame == nil then -- If no LastTrainCFrame exists, make one!
LastTrainCFrame = Train.CFrame -- This is updated later.
end
local TrainCF = Train.CFrame
local Rel = TrainCF * LastTrainCFrame:inverse()
LastTrainCFrame = Train.CFrame -- Updated here.
RootPart.CFrame = Rel * RootPart.CFrame -- Set the player's CFrame
--print("set")
else
LastTrainCFrame = nil -- Clear the value when the player gets off.
end
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect() -- Stop memory leaks
Function2:Disconnect() -- Stop memory leaks
end)
end)
GetTags(instance) returns an Array. You should use HasTag(instance, tag) instead, this should fix the issue with the spazzing.
Also you have a memory leak with the Died connection, move that died connection out of the heartbeat loop.
I slightly modified your script to work with unanchored objects moved by body movers. I changed the humanoid states to only work if you are falling or jumping, which lets Roblox handle the physical contact, and the script moves you back after you jump. I also adjusted the ray length, so it won’t push you back if you try to hop on from the front.
--BrahGames 07-27-2021 rewritten https://devforum.roblox.com/t/jailbreak-train-platform-system/236339
--slightly edited to work with bodymovers and such /maxx
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')
local CheckStates = true
local LastPartCFrame
local LastPart
local Function
local Function2
function CFrameLogic(Raycast, CFramePart)
--------------------------------------------------------------- MOVE PLAYER TO NEW POSITON FROM OLD POSITION
if Raycast.Instance ~= LastPart then
LastPart = Raycast.Instance
LastPartCFrame = nil
end
local Train = Raycast.Instance
if LastPartCFrame == nil then -- If no LastTrainCFrame exists, make one!
LastPartCFrame = Train.CFrame -- This is updated later.
end
local TrainCF = Train.CFrame
local Rel = TrainCF * LastPartCFrame:inverse()
LastPartCFrame = Train.CFrame -- Updated here.
CFramePart.CFrame = Rel * CFramePart.CFrame -- Set the player's CFrame
--print("set")
end
Function = RunService.Heartbeat:Connect(function()
--------------------------------------------------------------- CHECK PLATFORM BELOW
-- Build a "RaycastParams" object
local MovingObjects = workspace.MovingObjects --Make a folder and put all moving objects into it and call the folder "MovingObjects"
local HumanoidRootPart = player.Character.HumanoidRootPart
local humanoid = player.Character.Humanoid
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Whitelist
raycastParams.FilterDescendantsInstances = {MovingObjects}
raycastParams.IgnoreWater = true
-- Cast the ray
local Hit = workspace:Raycast(HumanoidRootPart.CFrame.p, Vector3.new(0,-15,0), raycastParams) --Casts a ray facing down
--------------------------------------------------------------------------------------------
if Hit and Hit.Instance:IsDescendantOf(MovingObjects) then -- Check if the ray hits and if it hits an object inside of MovingObjects
if CheckStates then -- check if the character is jumping
local currentState = humanoid:GetState()
if currentState == Enum.HumanoidStateType.Freefall or currentState == Enum.HumanoidStateType.Jumping or currentState == Enum.HumanoidStateType.FallingDown then
CFrameLogic(Hit, HumanoidRootPart)
else
LastPartCFrame = nil -- Clear the value when the player gets off.
end
else
CFrameLogic(Hit, HumanoidRootPart)
end
else
LastPartCFrame = nil -- Clear the value when the player gets off.
end
end)
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect() -- Stop memory leaks
Function2:Disconnect() -- Stop memory leaks
end)
It gets buggy when I hop over the other player because the ray is not ignoring him, which turns the script off momentarily.