LinearVelocity given XZ axis MaxAxesForce applies forces in different directions from the specified VectorVelocity

I am using a LinearVelocity to propel the player riding a hoverboard. The MaxAxesForce is being set to Vector3.new(1, 0, 1) * [SomeConstant] This prevents any Y influence from occurring as it is not desired. The issue here is that, I would like to have a Magnitude limit yet I only want it to apply on the XZ axis. If I don’t add the XZ restriction, it will attempt to keep my Y velocity at zero which does not allow my player to fall. This behavior results in my player swerving sideways when I am traveling diagonally for a second until it has sped up and then it goes straight.

Core issue is needing a MaxForce AS WELL as a MaxAxisForce. An example of how I would use that would be to set MaxAxisMagnitude to Vector3.new(math.huge, 0, math.huge) and set MaxMagnitude to like 20 * assemblyMass or something.

I have tried using the legacy BodyVelocity as well, but it suffers from the same issue.

Expected behavior
I need to limit velocity application to the XZ axis while having a magnitude limit on the velocity application.

Since you want to completely prevent the force from applying a force along the Y axis, can you use the Plane mode for the constraint? In Plane mode, you can use the magnitude force limit and you should get the behavior you want.

The problem with Plane mode is that when you switch directions that are on a non-uniform axis, it doesn’t impede the velocity that was built up on the other smaller axis and you end up having very poor character controls and you end up flinging into a wall.

		local newWay = false
		if newWay then
			controlLinearVel.VelocityConstraintMode = Enum.VelocityConstraintMode.Line
			controlLinearVel.ForceLimitMode = Enum.ForceLimitMode.Magnitude
			controlLinearVel.LineDirection = moveDirectionXZ.Unit
			controlLinearVel.LineVelocity = moveSpeed
			controlLinearVel.MaxForce = mass * moveForce
		else
			controlLinearVel.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
			controlLinearVel.ForceLimitMode = Enum.ForceLimitMode.PerAxis
			controlLinearVel.MaxAxesForce = xzAxis.Unit * mass * moveForce
			controlLinearVel.VectorVelocity = moveDirectionXZ * moveSpeed
			controlLinearVel.MaxForce = mass * moveForce
		end

While it technically worked, when you turn it has almost no control sometimes, due to the reasons I stated above.

Core issue is needing a MaxForce AS WELL as a MaxAxisForce. An example of how I would use that would be to set MaxAxisMagnitude to Vector3.new(math.huge, 0, math.huge) and set MaxMagnitude to like 20 * assemblyMass or something.

I have tried using the legacy BodyVelocity as well, but it suffers from the same issue.

From the behavior you describe and the script you posted, it sounds like you tried Line mode. I agree that it would suffer from the exact problem you describe. Plane mode should do what you want. So something like this:

controlLinearVel.VelocityConstraintMode = Enum.VelocityConstraintMode.Plane
controlLinearVel.ForceLimitMode = Enum.ForceLimitMode.Magnitude
controlLinearVel.PrimaryTangentAxis = moveDirectionXZ.Unit
controlLinearVel.SecondaryTangentAxis = moveDirectionXZ.Unit.Cross(Vector3.yAxis)
controlLinearVel.PlaneVelocity = moveSpeed * moveDirectionXZ.Unit
controlLinearVel.MaxForce = mass * moveForce

From a formulation point of view, this is identical to having a zero Y component for the MaxAxesForce and enforcing a magnitude force limit for the other two components. Let me know if that works for you. Thanks.

Will try shortly, thank you! Do you think this will also work for “slowing down”?

If you mean slowing down in the plane, then yes, it will work. Just set the velocity to zero and a force with magnitude less than the maxForce will be applied to bring the part to rest. The Y-Axis will be unaffected by the constraint so it won’t work for slowing anything down along that axes. You would need another constraint to do that.

			controlLinearVel.VelocityConstraintMode = Enum.VelocityConstraintMode.Plane
			controlLinearVel.ForceLimitMode = Enum.ForceLimitMode.Magnitude
			controlLinearVel.PrimaryTangentAxis = moveDirectionXZ
			controlLinearVel.SecondaryTangentAxis = moveDirectionXZ:Cross(Vector3.yAxis)
			controlLinearVel.PlaneVelocity = Vector2.new(moveDirectionXZ.X, moveDirectionXZ.Z) * moveSpeed
			controlLinearVel.MaxForce = mass * moveForce

I tried this. Note that moveDirectionXZ is already a unit vector. This seems to result in traveling in very random directions.

I also tried:

			controlLinearVel.PrimaryTangentAxis = Vector3.new(1, 0, 0)
			controlLinearVel.SecondaryTangentAxis = Vector3.new(0, 0, 1)

This works properly now using these parameters ^

1 Like

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