Hello! I’m working on a platformer. One of the skills the player can do is an airdash. I’ve made the basic functionality for the airdash, but I want to replicate Bomb Rush Cyberfunk’s airdash.
In particular, I’m trying to figure out how to make it so the dash inherits the player’s current velocity just like in BRC. I’ve made it so they aren’t affected by gravity during the duration of the airdash, but I’m stumped on how I can get the player’s current horizontal velocity.
Here’s my code (put in a local script)
local CAS = game:GetService("ContextActionService")
local RUS = game:GetService("RunService")
local RS = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")
local animator = humanoid:WaitForChild("Animator")
local HumanoidRootPart = character:WaitForChild("HumanoidRootPart")
local anim = RS.Assets.Animations.AirDash
local AirDashAnim = animator:LoadAnimation(anim)
local dashAttachment = Instance.new("Attachment")
dashAttachment.Name = "DashAttachment"
dashAttachment.Parent = HumanoidRootPart
local baseDash = CFrame.new(Vector3.new(HumanoidRootPart.CFrame.X, HumanoidRootPart.CFrame.Y, HumanoidRootPart.CFrame.Z))
local dashForce = Instance.new("VectorForce")
dashForce.Parent = HumanoidRootPart
dashForce.Attachment0 = dashAttachment
dashForce.ApplyAtCenterOfMass = true
dashForce.Force = Vector3.new(baseDash.LookVector.X * 20, 0, baseDash.LookVector.Z * 20) * 165
dashForce.Enabled = false
local isAirDashing = false
local function AirDash(actionName, inputState)
if actionName == "AirDash" and inputState == Enum.UserInputState.Begin and isAirDashing == false then
print("Player input airdash")
dashForce.Enabled = true
isAirDashing = true
workspace.Gravity = 0 -- Stop player from falling during the airdash
AirDashAnim:Play()
AirDashAnim.Ended:Once(function()
dashForce.Enabled = false
workspace.Gravity = 80 -- Return gravity to normal
end)
humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function()
isAirDashing = false -- When the player hits the ground again, let them airdash again next time
end)
end
end
RUS.Heartbeat:Connect(function()
if humanoid.FloorMaterial == Enum.Material.Air then
print("Player can airdash")
CAS:BindAction("AirDash", AirDash, false, Enum.KeyCode.Space)
else
CAS:UnbindAction("AirDash") -- No airdashing on the ground
end
end)
Also, if I modify workspace.Gravity for the player, would that mean that during the duration of the player’s airdash, things that are currently falling cannot fall until the airdash ends?
If you modify workspace.Gravity, things would stop accelerating downwards due to gravity. If you wanted to fix this, you’d need to use a bodymover or constraint on the HRP that counteracts the force of gravity.
To get the player’s horizontal velocity, you can use the velocity property of the HRP and disregard the Y value.
What I would do if I were you is to set the HRP’s velocity equal to itself without the Y component by creating a new vector3 from the X and Z values of the HRP velocity vector, then add a force instance to counteract gravity for the duration of the airdash. This method should remove any velocity acting upwards or downwards on the player whilst conserving horizontal velocity.
I believe the amount of force you use with whatever force instance you use should be equal to HRP.AssemblyMass * Workspace.Gravity
Unrelated to this, but this snippet of code you provided has a problem.
RUS.Heartbeat:Connect(function()
if humanoid.FloorMaterial == Enum.Material.Air then
print("Player can airdash")
CAS:BindAction("AirDash", AirDash, false, Enum.KeyCode.Space)
else
CAS:UnbindAction("AirDash") -- No airdashing on the ground
end
end)
You should also not be binding something every frame. It’d be better to use :GetPropetyChangedSignal(“FloorMaterial”) or humanoid states (as annoying as they are).
hello! Sorry for the late reply. To counteract gravity, would I simply have a VectorForce with a y value equal to HRP.AssemblyMass * Workspace.Gravity? Asking because I’m not sure which force constraint to use
gravity - Clipped with Medal.tv Here’s the above script in action. I’m not sure if the formula for counteracting gravity is correct or if I wrote it wrong, but you can see the character awkwardly falling during the duration of the dash.
Print the velocity before and after gravity force is enabled. Your gravityforce instance will only prevent counteract acceleration due to gravity, so if the object is moving downwards or upwards already it will maintain that velocity unless acted upon by a different force.
If the velocity before the force is enabled has a negative Y component, make sure to set the Y component of the HRP’s velocity to 0 at the time of the dash.
How come the player falling down during the dash happens although I define these (note velocityVector’s Y value as zero)
local playerVelocity = HumanoidRootPart.AssemblyLinearVelocity
local velocityVector = Vector3.new(playerVelocity.X, 0, playerVelocity.Z)
local dashForce = Instance.new("VectorForce")
dashForce.Parent = HumanoidRootPart
dashForce.Attachment0 = dashAttachment
dashForce.ApplyAtCenterOfMass = true
dashForce.Force = velocityVector
dashForce.Enabled = false
I access the player’s velocity, then set the force the dashing force will use with a Y value of 0. However, when I modify the AssemblyLinearVelocity of the player during the dash (with, say, Vector3.zero), the player doesn’t fall down? Should I be defining the dashForce when the dash is input?
Yes, you should, but also note that velocity and force are not the same thing, so you should not be setting dashForce’s force to velocity.
Velocity is distance/time (m/s), whilst force is the acceleration of mass. Setting the assemblylinearvelocity’s Y component to 0 is what you should be doing to remove the current vertical velocity. Keep the other components the same to conserve the horizontal velocity.
If you want to speed up the assembly horizontally, as a result of air dashing you should determine 2 things:
How much the assembly should accelerate
How long to accelerate the assembly
Using these 2 factors you can determine how much velocity you will receive by doing Acceleration * Duration. Since you are using a force, you need to set the force property to mass * acceleration to get the proper amount of mass to accelerate.
How can I conserve the player’s current velocity and still change their Y value? I can’t access the AssemblyLinearVelocity’s Y value directly although it’s a Vector3. If I could simply do that, I don’t need the dashForce (although I’ll probably use a modified form of it later)
I was able to enhance the player’s speed by simply adding a multiplier to their AssemblyLinearVelocity.X and Zs. It resulted in some comical amounts of speed when done during a slide, but I’ll iron those out. I’ll also add some logic with AlignOrientation, UIS:IsKeyDown, and RightVectors that instantly turns the player if they’re holding A or D during the airdash.