try splitting up the normal… CFrame.Angles(normal.X, normal.Y, normal.Z)
lol like I said, you’ll have to play with it. you probably only need 1 or 2 of the axis.
Oh, I see.
(30 charssssssssss)
So I tried this in a test env:
local RunService = game:GetService("RunService")
local Character = script.Parent
local RootPart = script.Parent.HumanoidRootPart
RunService.Heartbeat:Connect(function()
local downRay = Ray.new(RootPart.Position, Vector3.new(0, -10, 0))
local _, _, normal = workspace:FindPartOnRayWithIgnoreList(downRay, {script.Parent})
RootPart.CFrame = RootPart.CFrame * CFrame.Angles(normal.Z, 0, 0)
Character.Humanoid.PlatformStand = false
end)
This almost works… it seems to be fighting the default character controller though. I would suggest looking into the Gravity Controller suggested above and making a modified version to suit your needs. Sorry I can’t be of more help. GL
Thank u, I’ll try my best!
(30)
btw i figured out a better way
–R15
local char = game:GetService("Players").LocalPlayer.Character or game:GetService("Players").LocalPlayer.CharacterAdded:Wait()
local lowerTorso, rootPart = char:WaitForChild("LowerTorso"), char:WaitForChild("HumanoidRootPart")
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char}
params.FilterType = Enum.RaycastFilterType.Blacklist
game:GetService("RunService").Heartbeat:Connect(function()
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)
lowerTorso.Root.C0 = CFrame.new(0,-1,0,1,0,0,0,1,0,0,0,1) * CFrame.Angles(vector.z, 0, -vector.x)
end
end)
Thanks! It works very well!
(30CHARS)
hi that work on slope very well thanks!. But would I adjust that to work on straight wall please help and thanks!
for that you might want to look at EgoMoose’s gravity controller
Can there be a simple click stick to wall? That system confuse me sorry
thank you. I was trying to find a implementation for quaternion rotations that would work with the physics engine and this worked
would it be possible to maybe configure it so that it also works upside down? because I’m kinda just messing around, and thought it would be fun to have something you can walk on the ceiling of.
what kind of script is this? local or regular
local char = game:GetService("Players").LocalPlayer.Character or game:GetService("Players").LocalPlayer.CharacterAdded:Wait()
local lowerTorso, rootPart = char:WaitForChild("LowerTorso"), char:WaitForChild("HumanoidRootPart")
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char}
params.FilterType = Enum.RaycastFilterType.Blacklist
game:GetService("RunService").Heartbeat:Connect(function()
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)
lowerTorso.Root.C0 = CFrame.new(0,-1,0,1,0,0,0,1,0,0,0,1) * CFrame.Angles(vector.z, 0, -vector.x)
end
end)
Local
30rchar30echar30arcahr
local mag = vector.Magnitude
vector *= Vector3.new(1, 0, 1)
vector.unit
vector *= mag
should also be added between line 11 and 12 for precise rotation to the slope as well as line 9 should have:
lowerTorso.Root.C0.UpVector * (-char.Humanoid.HipHeight - (rootPart.Size.Y / 2) - 2)
as the direction for equal extension of the ray into the slope when rotated which helps tackle higher inclines.
Make the direction of the ray use the rootpart’s upvector scaled by negative of the size / 2 and hipheight, that should help in that department.
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)