No need for an apology I appreciate the response and I’ll take your advice.
I’ve seen tyridge77’s system in use and it works well albeit its some extra steps
No need for an apology I appreciate the response and I’ll take your advice.
I’ve seen tyridge77’s system in use and it works well albeit its some extra steps
Hey, sorry for necroposting but I feel like this is the best time to do this.
So I’ve got this issue with your script because I have a plane model that has multiple parts. However, the plane model doesn’t have one static part (RaftPart) so it’s teleporting me around like crazy.
Shown here:
https://i.gyazo.com/f607b2e739cb9bb0065ff3fd591dcb1f.mp4
Here’s my code (It’s modified to suit my needs):
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')
local LastTrainCFrame
local Function
local Function2
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 = workspace:FindPartOnRay(ray,Ignore)
if Hit and Hit:IsDescendantOf(workspace.Planes) then
local Train = Hit
if not LastTrainCFrame then
LastTrainCFrame = Train.CFrame
end
local TrainCF = Train.CFrame
local Rel = TrainCF * LastTrainCFrame:inverse()
LastTrainCFrame = Train.CFrame
RootPart.CFrame = Rel * RootPart.CFrame
else
LastTrainCFrame = nil
end
if not Function2 then
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect()
Function2:Disconnect()
end)
end
end)
Any idea on how to fix this? (btw it’s late for me so i will be going to bed after posting this)
To switch static parts you have to convert Rel from the local space of the old Train part into the new Train part.
Hi, I just tried to apply this with a ship, with a whitelist for the ray.
If I don’t move on the ship while the ship is moving, I start sliding towards the front. Any way to fix this?
Here is my code:
local Players = game:GetService("Players")
local player = game.Players.LocalPlayer
local RunService = game:GetService('RunService')
local LastTrainCFrame
local Function
local Function2
Function = RunService.Heartbeat:Connect(function()
local RootPart = player.Character.Torso
local ray = Ray.new(RootPart.CFrame.p,Vector3.new(0,-50,0))
local WhiteList = {workspace.Orion["Cruiser Kappa"]["Cruiser Kappa"].Ship.MovingPart}
local Hit, Position, Normal, Material = workspace:FindPartOnRayWithWhitelist(ray,WhiteList)
if Hit and Hit.Name == "MovingPart" then
local Train = Hit
if LastTrainCFrame == nil then
LastTrainCFrame = Train.CFrame
end
local TrainCF = Train.CFrame
local Rel = TrainCF * LastTrainCFrame:inverse()
LastTrainCFrame = Train.CFrame
RootPart.CFrame = Rel * RootPart.CFrame
else
LastTrainCFrame = nil
end
Function2 = player.Character.Humanoid.Died:Connect(function()
Function:Disconnect()
Function2:Disconnect()
end)
end)
For easier solution I would recommend using BodyMovers
so Roblox will take care of physics.
A topic from back in May deals with the same behavior, except the issue wasn’t the same.
This topic is really old and I remember when it first was posted.
But this is a ModuleScript that I used for making a Roundabout that you would see at a Playground
It should give you a general idea of how to make it.
Only works on LocalScripts.
local module = {}
local Collection = game:GetService("CollectionService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Map = workspace:WaitForChild("Map")
local Infrastructure = Map:WaitForChild("Infrastructure")
local Folder = Infrastructure:WaitForChild("Roundabouts")
local Camera = workspace.CurrentCamera
local Ignore = {}
local function ExitRoundabout(Roundabout)
warn("Exited")
end
local function EnterRoundabout(Roundabout)
warn("Entered")
end
local CFrameSpinners = {}
local Roundabouts = {}
function module.Init()
local DownVector = Vector3.new(0, -1, 0)
local newRay = Ray.new
local FindPartOnRay = workspace.FindPartOnRay
local FindPartOnRayWithIgnoreList = workspace.FindPartOnRayWithIgnoreList
local function fpor(start, direction, distance, IgnoreModel, WhitelistFolder)
local attempt = 0
local hit, pos, origin, material = nil, start, -direction, nil
while distance > 0 and attempt < 10 do
local ray = newRay(start, direction * distance)
hit, pos, origin, material = FindPartOnRay(workspace, ray, IgnoreModel, false, true)
local d = (start - pos).Magnitude
if hit and (hit:IsDescendantOf(WhitelistFolder) or hit.CanCollide) then
return hit, pos, origin, material
end
start = pos
distance = distance - d
attempt = attempt + 1
end
return hit, pos, origin, material
end
local LastRoundabout
local lt = tick()
local function Heartbeat()
local t = tick()
local dt = t - lt
lt = t
local RoundaboutModel, Spinner, SpinnerCf, RootPart
local Character = LocalPlayer.Character
if Character then
local Humanoid = Character:FindFirstChild("Humanoid")
if Humanoid then
RootPart = Humanoid.RootPart
if RootPart then
RoundaboutModel = fpor(RootPart.Position, DownVector, 10, Character, Folder)
if RoundaboutModel and not RoundaboutModel:IsDescendantOf(Folder) then
RoundaboutModel = nil
end
end
end
end
if not RoundaboutModel then
if LastRoundabout then
ExitRoundabout(LastRoundabout)--Exited LastRoundabout
end
LastRoundabout = nil
end
local ClosestDist, ClosestRoundabout = 500, nil
for i,Roundabout in pairs(Roundabouts) do
local TSpinner = Roundabout:FindFirstChild("Spinner")
if RootPart then
if TSpinner then
local Dist = (RootPart.Position - TSpinner.Position).Magnitude
if ClosestDist >= Dist then
ClosestDist = Dist
ClosestRoundabout = Roundabout
end
if CFrameSpinners[TSpinner] == nil then
CFrameSpinners[TSpinner] = TSpinner.CFrame
end
end
end
if RoundaboutModel and RoundaboutModel:IsDescendantOf(Roundabout) then
Spinner = TSpinner
SpinnerCf = CFrameSpinners[TSpinner]
if not LastRoundabout then
EnterRoundabout(Roundabout)--Entered
elseif LastRoundabout ~= Roundabout then
ExitRoundabout(LastRoundabout)--Exited LastRoundabout
EnterRoundabout(Roundabout)--Entered Roundabout
end
LastRoundabout = Roundabout
else
CFrameSpinners[TSpinner] = TSpinner.CFrame
end
end
if Spinner then
local NewCF = Spinner.CFrame
if CFrameSpinners[Spinner] == nil then
CFrameSpinners[Spinner] = NewCF
end
SpinnerCf = CFrameSpinners[Spinner]
local Relative = NewCF * SpinnerCf:Inverse()
RootPart.CFrame = Relative * RootPart.CFrame
local CamRel = Camera.CFrame:ToObjectSpace(Camera.Focus)
Camera.CFrame = Camera.CFrame * CamRel * (Relative - Relative.p) * CamRel:Inverse()
CFrameSpinners[Spinner] = Spinner.CFrame
end
end
RunService.Heartbeat:Connect(Heartbeat)
local function RoundaboutAdded(Model)
table.insert(Roundabouts,Model)
end
local function RoundaboutRemoved(Model)
for index,value in pairs(Roundabouts) do
if value == Model then
table.remove(Roundabouts,index)
end
end
end
for _, Model in next, Collection:GetTagged("Roundabout") do
RoundaboutAdded(Model)
end
Collection:GetInstanceAddedSignal("Roundabout"):Connect(RoundaboutAdded)
Collection:GetInstanceRemovedSignal("Roundabout"):Connect(RoundaboutRemoved)
end
return module
It doesn’t work even when my vehicle floor is named “RaftTop”
Are you sure you are setting it up correctly? Worked fine for me a few weeks ago and I doubt it changed.
Yeah I put the script in StarterPlayer > StarterPlayerScripts and I used the script as a local script. It worked once but the second time I tried didn’t work
You have to make sure that your cframing your vehicle. And make sure to whitelist only that raft top part for the ray, so it wont get blocked by others. lol okkkk
Basically what it is. when you jump you go back according to roblox physics.But how they fixed this is the speed the player goes back.means if he jump he goes back by 15 studs.They added a script which pushes the player 15 studs front exactly when the player jumps.so -15 + 15 = 0
so they player stays at the spot and dosen’t move back.
Hey, so I am very new to scripting and I was wondering if you put the script in the part that you stand on?
No. You put it in starter character scripts.
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)