This was kind of a fun one, as I was looking for such a solution. Next step was to replicate the movement so other players also see the movement.
Local script 1
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local moveEvent = ReplicatedStorage:WaitForChild("EventsFolder"):WaitForChild("PlayerCustomMovementEvent")
local tiltFunction
local playerTerminated
tiltFunction = RunService.Heartbeat:Connect(function()
local char = Players.LocalPlayer.Character
local lowerTorso, rootPart = char:WaitForChild("LowerTorso"), char:WaitForChild("HumanoidRootPart")
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char}
params.FilterType = Enum.RaycastFilterType.Blacklist
local ray = workspace:Raycast(rootPart.Position, Vector3.new(0, -char.Humanoid.HipHeight - (rootPart.Size.Y / 2) - 2, 0), params)
if ray then
local vector = rootPart.CFrame:VectorToObjectSpace(ray.Normal)
local newCFrame = CFrame.new(0,-0.9,0,1,0,0,0,1,0,0,0,1) * CFrame.Angles(vector.z, 0, -vector.x)
lowerTorso.Root.C0 = newCFrame
moveEvent:FireServer(lowerTorso.Root, newCFrame)
end
playerTerminated = char.Humanoid.Died:Connect(function()
tiltFunction:Disconnect()
playerTerminated:Disconnect()
end)
end)
Local script 2
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local moveEvent = ReplicatedStorage:WaitForChild("EventsFolder"):WaitForChild("PlayerCustomMovementEvent")
moveEvent.OnClientEvent:Connect(function(otherPlayer, cframe_target, cframe_position)
cframe_target.C0 = cframe_position
end)
Server script
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local moveEvent = ReplicatedStorage:WaitForChild("EventsFolder"):WaitForChild("PlayerCustomMovementEvent")
moveEvent.OnServerEvent:Connect(function(player, cframe_target, cframe_position)
for _, sendToPlayer in pairs(Players:GetChildren()) do
if sendToPlayer ~= player then
moveEvent:FireClient(sendToPlayer, player, cframe_target, cframe_position)
end
end
end)