I’m having a problem where if you were to traverse up a slope, it would either be very glitchy or stop you.
Someone suggested me a workaround which is to change the velocity of the parts like a conveyor but it’s still somewhat glitchy.
As you know, Speed Run 4: Speed Run 4 🍩😋[UPDATE] - Roblox was able to accomplish this smooth movement but I really don’t know how they were able to achieve it?
My guess is that he used body force or something to make it more smooth but for now, I honestly have no clue how he was able to do this? Any ideas on how this was done?
If you know the surface your character is standing on, project Humanoid.MoveDirection onto that surface’s normal plane, then move in that direction. This could be done either by setting velocity or using an “impulse” in the BodyForce, e.g., for .1 seconds, provide 10x the amount of acceleration you need to get to the target velocity.
When I did this stuff for Vurse, the characters were fully custom, so the BodyForce was also responsible for keeping the player off the ground. If you do something similar, make sure you offset gravity appropriately.
Why did the characters need to be custom and what did you add on them? Did you just add a bodyforce to like the humanoidrootpart inside the custom character and use it when needed?
In my case, I put the character in physics mode and controlled it manually. If you just need to make running up/down slopes smoother, you can definitely do without it.
@3rdhoan123, bodyforce should be proportional to the character’s mass.
If you don’t mind (you don’t have to tho), could you provide a pseudo-code? I’ve been trying to attempt it but it would always either send me flying into the air or just not work at all.
I think you can use the cross product from the surface normal provided by the ray and the BodyForce's current force to figure out a new axis to turn the force in, and use the dot product to find how large the change in angle should be. Probably something like this:
local BodyF = -- the bodyforce
local hit, contact, normal = workspace:FindPartOnRay(...)
local axis = BodyF.Force.Unit:Cross(normal)
local dot = BodyF.Force.Unit:Dot(normal)
-- the closer to 0 for dot, the softer the angle
local angle = math.asin(dot)
-- you can probably also use math.pi/2 - math.acos(dot)
if axis ~= Vector3.new() then
BodyF.Force = CFrame.fromAxisAngle(axis.Unit, angle) * BodyF.Force -- * 10 ?
else -- force is perpendicular to normal
BodyF.Force = CFrame.Angles(math.pi/2,0,0) * BodyF.Force.Magnitude
end
I’m sorry that this isn’t pseudocode since it is too technical for me to explain, as I’m trying to connect the dots too.
This would of course be applied in a loop, checking for hit's existence first. I can’t test this because I’m on mobile, so I may be absolutely wrong with this solution!
Edit: If the BodyForce pushes you further into the slope, try negating axisorangle. They will both do the same thing though, so personal preference.
BodyForce.Force requires a Vector3. Additionally, you’re trying to multiply a CFrame, which simply isn’t possible in the way you’re doing it.
Essentially, since you’re intending to define an angle for the Vector using CFrame.Angles(), you can use this to construct a directional unit vector, and finally multiply this new vector by the Force’s magnitude.
Sorry to bump this, but I’m having the same problem, but I managed to fix them.
What I did is just like @blobbyblob said, added BodyForce + BodyGyro to the HRP and updated them every tick. There was Two BodyForces used in this situation. One is for “Gravity”, and the second one is for controlling the character while running up slope (The most important one).