Linearvelocity problem

i am making a custom movement system with linearvelocity, i found this tutorial on youtube and decided to implement it but it’s too slidey for my liking, i want the little slide once the player stops moving but when the player is turning it’s like sliding on ice, which i don’t really like

local linearVelo = Instance.new("LinearVelocity", rootpart)
linearVelo.Attachment0 = rootAttachment
linearVelo.MaxForce = 800
linearVelo.VelocityConstraintMode = Enum.VelocityConstraintMode.Plane
linearVelo.RelativeTo = Enum.ActuatorRelativeTo.World
linearVelo.PrimaryTangentAxis = Vector3.new(1, 0, 0)
linearVelo.SecondaryTangentAxis = Vector3.new(0, 0, 1)
bindToRenderStep("Movement", 1, function(step)
	local moveDir = hum.MoveDirection
	local targetVelo = Vector2.new(moveDir.X, moveDir.Z) * maxSpeed
	local deltaVelo = targetVelo - linearVelo.PlaneVelocity
	linearVelo.PlaneVelocity += deltaVelo * 2.5 * step
end)
1 Like

bump please i have been trying to figure this out for months :sob:

1 Like

Hey again! I was away for a few days, but I saw your reply on the other thread and decided to do some experimentation.

In order to test out the issue of the slow falling against the wall (from the other thread), I dug up a module that I made a while back that—incidentally—aims to mitigate the exact issue you mention right here. I wanted to ask on the other thread if you were perhaps using a custom movement system because of the sliding issue, but I felt it would be too off-topic.

Anyway, to start off, here’s a testing place: Project: Player Speed Movement Damping - Roblox. I updated the interface and map a little bit in response to your threads.

Addressing sliding

Sliding is just the effect of slow acceleration. If you do intend to stick with the LinearVelocity movement, then this should just be a matter of changing the acceleration function. Wherever you’re handling acceleration in response to user input, just bump those terms up a little bit and you should feel some better control.

With default movement, the issue shows itself at higher speeds. Addressing it is relatively simple, though. You determine where the user wants to go by reading their character’s movement vectors with respect to their input (WASD, stick, etc.); and then you apply a counteracting force to the player’s character whenever there’s delta between the user input and the actual movement vector of the character. It’s essentially a subtractive PID controller.

This results in better handling for your characters.


Sticky walls

The above is great in a vacuum! But we start to see the issues that were hidden before:

And comparing that to what happens without the damping:



And just to confirm my suspicions, I trialed it with just the normal 16 walk speed and no movement modifications.




It’s almost as if there were a frictional force from the wall… :thinking:

There are a few oddities here. First of all, our character is super bouncy. Obviously if we threw a real, inelastic object with this kind of velocity at a solid wall, it would either shatter or splat. Without damping we just bounce off, and that’s kind of the next best thing. The only difference between the damping and sans-damping trials is that of the accelerations. The damping almost immediately counteracts the force from hitting the wall, so when I keep my forward key pressed down, the merits of applying that “force” from my keyboard input are more apparent than that of the keyboard input without the damping.

This broaches the second inconsistency. In real life, we can’t just apply a force to ourselves from some extradimensional controller. We move ourselves by applying a force in an equal and opposite direction of where we wish to move. To walk forward, I push my legs backward against the earth. The character in Roblox (and most games for that matter) don’t do this. The keyboard input is that extradimensional force that moves them, which looks fine for the most part, but it looks very odd when we’re able to freely accelerate our character in mid-air. In this particular instance, we’re finding ourselves able to apply an invisible and unrealistic force strong enough to hold our characters against a wall.

There are a few ways to tackle this, but I think I’ll opt to restrict mid-air movement in my module. By limiting mid-air movement, the player won’t be able to generate enough “5D force” to keep themselves pressed against whereas they should be falling.

So yeah, it’s another out-of-the-box interaction and otherwise logical interaction that can result in unsatisfying movement. The only solution is to build around it. I’ll probably work on something since the movement damping exaggerates the effect at high speeds. But for now, I’ll just refactor the module and post it here when I’m done. Of course, you can also try implementing it yourself. Like I said, it’s not too complex.

I know this is an answer for two separate topics, but I feel that they are interconnected enough to warrant one big answer rather than two small and somewhat redundant ones. Also, I apologize if some of this is incoherent. I’m operating off of a few hours of sleep, and I tend to get a little “preachy” when I’m tired. Lol.

If I were you, I would just use roblox’s CustomPhysicalProperties and change things like Friction, density, and elasticity and mess around with how all of that is handled with the mass of the character.

This is a simple solution to your issue as it requires little to no coding, please try it out, and if it does not help, you can read the yap-session that is the reply above mine.

Fair. Density is the only one that’s going to have enough flexibility to do anything meaningful. None of it those properties, including density, will have any effect on your LinearVelocity movement, so you’ll need to revert. If you do go for density, just be wary of how that will cause your characters to interact with other aspects in your game. And you’ll still have to do a little bit of math and coding if you intend on having a wide range of speeds, albeit not as much.

You’ll still have to manage the wall stickiness as a separate issue, which was the bulk of my response.

This (Releasing Character Physics Controllers) wasn’t a feature when I originally wrote the module, but it looks promising from what little I’ve read so far. It may have some of the answers you’re looking for.

Hi @Deimesa, I appreciate your “preachy” explanation of my problem! However, I’ve actually found an alternative way to counteract “player being too slidey” and “player getting stuck on the wall”. I feel kinda bad because of the amount of information you’ve provided me but the solution was easier than you think. Don’t worry I’ll be explaining what I’ve done to achieve it. But firstly,

I am making this custom movement to make a fully functional parkour movement game, similar to Parkour Reborn and Orion Protocol, but I am currently leaning more towards Orion Protocol because of the realism.

The slidey issue:

The code:

local linearVelo = Instance.new("LinearVelocity", rootpart)
linearVelo.Attachment0 = rootAttachment
linearVelo.MaxForce = 800
linearVelo.VelocityConstraintMode = Enum.VelocityConstraintMode.Plane
linearVelo.RelativeTo = Enum.ActuatorRelativeTo.World
linearVelo.PrimaryTangentAxis = Vector3.new(1, 0, 0)
linearVelo.SecondaryTangentAxis = Vector3.new(0, 0, 1)
bindToRenderStep("Movement", 1, function(step)
	local moveDir = hum.MoveDirection
	local targetVelo = Vector2.new(moveDir.X, moveDir.Z) * maxSpeed
	local deltaVelo = targetVelo - linearVelo.PlaneVelocity
	linearVelo.PlaneVelocity += deltaVelo * 2.5 * step
end)

This is mainly the problem I have with my custom movement system, but through some experimentation and messing around with the code, I’ve merely just adjusted
the 2.5 value in relative to the linearVelocity Magnitude.
It goes something like:

local targetVelo = Vector2.new(moveDir.X, moveDir.Z) * maxSpeed
local deltaVelo = targetVelo - linearVelo.PlaneVelocity
local increment = lerp(1, 6, math.clamp(linearVelo.PlaneVelocity.Magnitude/21, 0, 1))
linearVelo.PlaneVelocity += deltaVelo * increment * step

This is the result:


As you can see, compared to the original thread’s video, it’s must less slidey - especially when the player is turning.

The “player getting stuck on the wall” issue:

The reason why I am making a capsule collider in the first place is that when the player is performing parkour movements, the default character’s collision may affect god knows what.

Indeed, it was the mover constraints that were causing this issue, and until now I still have no clue why and how it happened, but through some research in the DevForum I came across this post:

Similarly, all I did was detect the parts within my radius and then raycasting to get the normal, then feel it into:

local function reflectiveForce(ray)
			if ray and (ray.Instance.CanQuery or ray.Instance.CanCollide) then
				local normal = ray.Normal
				local reflection = moveDir - 2 * moveDir:Dot(normal) * normal -- Reflection=Incident−2×Incident⋅Normal×Normal
				linearVelo.PlaneVelocity = Vector2.new(reflection.X, reflection.Z) * moveDir.Magnitude * 2.5
			end
		end

Here is the result:

As for:

I’ve also utilise CustomPhysicalProperties! I check if the player is falling then apply more to the HumanoidRootPart’s density.

Once again, thank you for your comments and your help. Sorry for not informing you that this problem was been solved long ago, I thought no one was gonna come back to this thread lol.

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.