So I’ve developed a slide system that aims to be a similar to the sliding on the game Grace, and I’ve been having some doubts on how to make something like that.
I’ve been using a BodyVelocity, which from research is pretty antiquated, but I don’t seem to see any other alternatives, since many of the others I’ve tried like LinearBodyVelocity / AngularBodyVelocity just make the player not have a gravity.
The biggest problem I have is just that the player gets stuck to walls and cannot get “unstuck” until they stop sliding, and I’d like that to not happen at any case
So if anyone has any idea on how to make something like this, it would help a lot!
(Footage and Script below)
local plr = game.Players.LocalPlayer
local char = plr.Character
local uis = game:GetService("UserInputService")
local root = char.HumanoidRootPart
local camera = workspace.CurrentCamera
local rp = RaycastParams.new()
rp.FilterType = Enum.RaycastFilterType.Exclude
rp.FilterDescendantsInstances = {char}
local dS = 16
local cS = 0
local hasStarted = false
local s = char.Humanoid:LoadAnimation(script.slidin_anim)
local can = true
char.Humanoid.StateChanged:Connect(function(ol, new)
print("d")
if new == Enum.HumanoidStateType.Freefall then
if math.abs(char:WaitForChild("HumanoidRootPart").AssemblyLinearVelocity.Y) > 10 then
can = true
end
else
can = false
end
end)
while task.wait() do
if (uis:IsKeyDown(Enum.KeyCode.LeftControl) or uis:IsKeyDown(Enum.KeyCode.RightControl)) and char.Humanoid.FloorMaterial ~= Enum.Material.Air then
local i = 30
local slide = Instance.new("BodyVelocity")
slide.Velocity = char.HumanoidRootPart.CFrame.LookVector * i
slide.MaxForce = Vector3.new(1,0,1) * 30000
slide.Parent = root
script.slide_sfx:Play()
repeat
script.slide_sfx.PlaybackSpeed = 1 + i/100
s:Play()
char.Humanoid.CameraOffset = Vector3.new(0,0,0):Lerp(Vector3.new(0, -1.5, 0), 0.25)
slide.Velocity = char.HumanoidRootPart.CFrame.LookVector * i
local deltaY = char.HumanoidRootPart.Velocity.Y;
local deltaX = (char.HumanoidRootPart.Velocity*Vector3.new(1,0,1)).Magnitude;
local r = workspace:Raycast(char.HumanoidRootPart.Position, -Vector3.yAxis * 25, rp)
if deltaY/deltaX > 0 and can == false then
if r then
print(r.Instance)
print(r.Material)
if (r.Instance:IsA("Part") and r.Instance.Shape == Enum.PartType.Wedge) or (r.Instance:IsA("WedgePart")) then
i /= 1.025
end
end
i /= 1.005
else
if can == false then
i *= 1.02
end
end
task.wait()
until not uis:IsKeyDown(Enum.KeyCode.LeftControl) or i < 0
s:Stop()
script.slide_sfx:Stop()
char.Humanoid.WalkSpeed = 16
game.Debris:AddItem(slide, 0.05)
repeat
char.Humanoid.CameraOffset = Vector3.new(0,0,0):Lerp(Vector3.new(0, 0, 0), 0.25)
task.wait()
until char.Humanoid.CameraOffset == Vector3.new(0,0,0)
else
hasStarted = false
cS = 0
end
end
I know it’s very late, but I really like how it turned out and I’d like to do something similar in my game. That said, I have a question: ¿How do you get the animation to rotate the player’s legs 90 degrees into the air? I can’t pass from 70 degrees or so
I mean that animations typically have a limit on how much a part of the body can be rotated, mostly to avoid unrealistic positions (for example, you can’t have an animation where the player"s leg rotated 180º into the air).
I was also making a sliding system when I came across your post, and I needed to make a placeholder animation, and I wanted to rotate the body 90º in order for it to adhere to the ground (although I eventually settled in a simple sitting animation like yours for now). I eventually figured out that with platformstand = true the animation rotation limit didn’t affect the animation. I guess that also works with the Freefall humanoid state.
Anyways, I did end up ditching the project because it was too complicated for my skill level, but thanks for your slide script because it was a really good reference for when I was stuck
I just need to know how to add a downward force or something, so the character stays in the slope
if anyone knows how to do that, tell me
(I’ve used a linear velocity now)
Sorry for being late and a bit too insistent but anyways. I thought that for adding downwards velocity in a slope you could make a raycast going straight down to the player, enough to detect when there’s a slope below the player. Then, if the raycast detects something (in this case a part), you can access its normal. The normal of a wall/floor/anything 3D, in case you didn’t know, is a vector drawn in the direction is pointing. A 3D objects has many normals, as many as faces, as every face faces one direction. Because of that, if the raycast detects a floor, its normal will be a vector facing upwards. However, if it’s a slope, it will be a vector facing in a diagonal direction (that is, x and z aren’t 0). Using that, you can easily check for a slope, (x and/or z aren’t 0), it’s direction (the normal vector without the y parameter) and how steep it is (I think it’s the greater the x and z values the steeper, but you’d have to check). Anyways, in this case you only need the steepness, which you can convert into a number (e.g. if what I said was correct, steepness = normal.x + normal.z, but any method you find is also valid) and apply a downwards velocity based on that number, that is, the greater the steepness, the greater the downwards force. That or, to simplify, you could just check if it’s a slope and apply a downwards force regardless of the steepness. I don’t know if both of them could work well with how your sliding system works, but if you’re stuck with what to do, try this. Although, as far as I’m aware, you still need the normal to check if you’re on a slope, though.