Replicating a Bomb Rush Cyberfunk-style air dash

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.

Here’s a clip with it in action. brc - Clipped with Medal.tv

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?

Update: No luck thus far. If anyone has any insights I’d love to hear.

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).

1 Like

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

Here’s a portion the code I made, if you want to take a look. I added the playervelocity, velocityvector, and gravityforce as well.



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 

local gravityForce = Instance.new("VectorForce")
gravityForce.Parent = HumanoidRootPart
gravityForce.Attachment0 = dashAttachment
gravityForce.ApplyAtCenterOfMass = true
gravityForce.Force = Vector3.new(0, HumanoidRootPart.AssemblyMass * workspace.Gravity, 0)
gravityForce.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
		gravityForce.Enabled = true 
		isAirDashing = true 
		AirDashAnim:Play()
		
		AirDashAnim.Ended:Once(function()
			dashForce.Enabled = false 
			gravityForce.Enabled = false
		end)
		
		humanoid:GetPropertyChangedSignal("FloorMaterial"):Connect(function() 
			isAirDashing = false -- When the player hits the ground again, let them airdash again next time 
		end)
	end
end

I believe a vectorforce would work. You can use a bodyforce if you want but do note it is deprecated.

1 Like

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:

  1. How much the assembly should accelerate
  2. 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.

1 Like

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)

AssemblyLinearVelocity = Vector3.new(AssemblyLinearVelocity.X, 0, AssemblyLinearVelocity.Z)

1 Like

This works! Here’s the dash in action. working! plus totally real movement tech - Clipped with Medal.tv

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.

1 Like

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