I initially assumed anchored parts on the client being moved using CFrame and TweenService would work with Moving Platforms although it appears they don’t:
I don’t think you can use tweens for this sort of thing, because Tweening doesn’t consider physics, if you use things like bodygyro or body position, it’ll take physics into consideration and it’ll start working.
you can also tween the properties of BodyPosition & BodyGyro if you really need the tween service.
@ForeverHD I wouldn’t use a custom character controller, then you would have to learn a new character controller system.
and It also only takes 2-4 lines of code, you don’t need raycasting or any special math either.
you just have to remember that tweening object CFrames will bypass any physics, BUT if you tween body position or gyro’s then its the opposite.
Thanks all for the replies. For anyone reading in the future, here’s some simplified code based on EgoMoose’s WallStick to achieve the effect:
-- LOCAL
local runService = game:GetService("RunService")
local players = game:GetService("Players")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local hrp = character:WaitForChild("HumanoidRootPart")
local gap = 0.1
local offsetY = -hrp.Size.Y * 1.5
local previousPart
local previousMovingPartCFrame
-- STICK
runService.Heartbeat:Connect(function(step)
if humanoid.Health <= 0 then
return
end
local origin = hrp.Position + Vector3.new(0, offsetY+gap, 0)
local lookDirection = origin + Vector3.new(0, -1, 0)
local ray = Ray.new(origin, (lookDirection - origin).unit * gap*2)
local movingPart, standingPos = workspace:FindPartOnRay(ray, character)
if movingPart and previousMovingPartCFrame and movingPart == previousPart then
local offset = previousMovingPartCFrame:toObjectSpace(hrp.CFrame)
hrp.CFrame = movingPart.CFrame:toWorldSpace(offset)
end
previousPart = movingPart
previousMovingPartCFrame = movingPart and movingPart.CFrame
end)
I may be extremely late(4 months late to be exact) but some people such as myself might stumble upon this thread and find this reply helpful. Try putting this into a local script in startercharacter, it isn’t perfect but I made it entirely local and updated the raycast to workspace:raycast due to the raycast inside the other script being deprecated.
-- LOCAL
local runService = game:GetService("RunService")
local players = game:GetService("Players")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local hrp = character:WaitForChild("HumanoidRootPart")
local gap = 0.1
local offsetY = -hrp.Size.Y * 1.5
local previousPart
local previousMovingPartCFrame
local movingPart
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {character}
-- STICK
runService.RenderStepped:Connect(function(step)
if humanoid.Health <= 0 then
return
end
local origin = hrp.Position + Vector3.new(0, offsetY+gap, 0)
local lookDirection = origin + Vector3.new(0, -1, 0)
local ray = workspace:Raycast(origin, ((lookDirection - origin).unit * gap*2), raycastParams)
if ray then
movingPart = ray.Instance
end
if movingPart and previousMovingPartCFrame and movingPart == previousPart then
local offset = previousMovingPartCFrame:toObjectSpace(hrp.CFrame)
hrp.CFrame = movingPart.CFrame:toWorldSpace(offset)
end
previousPart = movingPart
previousMovingPartCFrame = movingPart and movingPart.CFrame
end)