I’m using the AssemblyLinearVelocity property in order to create a dashing system for my game.
I’m not using BodyVelocity as it proves to be unreliable for fast paced fighting games, since it has a small delay between the client who creates it and others clients.
The issue is that the distance travelled by dashing is much bigger when the player is in the air, as there is no friction with the ground. I already tried removing friction for all body parts but it did not fix it.
Here’s my code :
function force.createDash(character,length,speed,yVelocity,side)
local rootPart = character:FindFirstChild("HumanoidRootPart")
local connection = RunService.RenderStepped:Connect(function()
local velocity
if side then
velocity = rootPart.CFrame.RightVector * speed + Vector3.new(0,yVelocity,0)
else
velocity = rootPart.CFrame.LookVector * speed + Vector3.new(0,yVelocity,0)
end
character:FindFirstChild("HumanoidRootPart").AssemblyLinearVelocity = velocity
end)
task.wait(length)
connection:Disconnect()
end
(I’m setting the property itself rather than using ApplyImpulse, as the problem is even worse otherwise)
I normally use a VectorForce and I think it should solve your problem, the main problem is that in the air the character has no friction so he can more freedly slide.
The code is in the function createDash from the initial message, they’re passed as arguments. In my testing the yVelocity is always set to 0 so it’s irrelevant.
That’s basically my problem, the distance travelled in the air is different and if the velocity is quite high, then the difference is very noticeable and problematic.
By multiplying by the mass of the character, the distance is increased both when dashing on the ground and in the air, so it doesn’t seem to solve much.
Changing the force here doesn’t help in any way because the speed in the air will always be higher than the speed on the ground, in a way multiplying by the mass just results in an higher speed but doesn’t solve much.
The speed is an arbitrary value which is chosen randomly pretty much, in the first comment I used a speed of 70 and a length of 0.3 to achieve the effect.
Ok way I’m going to describe is how I do it on my games, and it’s kind of a pain (but works). In your RenderStepped connection, check if the player is on the ground (can be done with raycasts down or maybe checking the humanoid.FloorMaterial to see if it’s Air. Then from there, if it’s in the air you check the current velocity local iterateVelocity = character.PrimaryPart.AssemblyLinearVelocity and adjust the new force based off the speed it’s going. Velocity = Distance/Time
Yes but Distance/Time doesn’t result in a vector which is required when setting the AssemblyLinearVelocity. Do you multiply this result to the current velocity ? I’m slightly confused.
It’s different from what you’re currently doing because the distance and time are going to be variables in the loop. time is the elapsed time since you started the dash and distance is the remaining distance to the destination
local goalFrame = CFrame.new(0, 0, -5) --Dashes the player 5 studs infront
local maxDashTime = 1 --the amount of time you want the player to dash, so for this example 1 second
local elapsedTime = 0
local distanceOffset = 5
local goalDistance = character.PrimaryPart.CFrame * goalFrame
local connection = nil
connection = RunService.Heartbeat:Connect(function(step)
elapsedTime+=step --new time
distanceOffset = (character.PrimaryPart.CFrame.Position - goalDistance.Position).Magnitude --new distance
if elapsedTime >= maxDashTime then --When 1 second is elapsed, close connection
connection:Disconnect()
connection = nil
end
end)