Hello, I’m trying to make a dashing script with BodyVelocity and want the dashing to last until the player stops holding a certain key on their keyboard.
The issue is I am trying to figure out how to make the dashing end at a given time while the player is holding a key.
I tried doing a while true do loop and whenever i press E it just keeps moving me with no end or stopping to it
heres the script:
if input.KeyCode == Enum.KeyCode.E then
KeyPressed = true
print("player is pressing E")
while true do
wait()
player.Character.HumanoidRootPart.Velocity = player.Character.HumanoidRootPart.CFrame.lookVector * 50
end
end
UIS.InputEnded:Connect(function(input)
if input.KeyCode == Enum.KeyCode.E then
KeyPressed = false
if print("E key isnt being held")then
player.Character.HumanoidRootPart.Velocity = player.Character.HumanoidRootPart.CFrame.lookVector * 0
end
One trick with InputObjects is that once you’ve got a reference to that object, you can set up a connection that responds to changes in just that InputObject.
When UserInputService.InputBegan fires, it passes along an InputObject representing e.g. the action of pushing the E key. That InputObject has a Changed event, which we can listen to and which fires when te E key is released again. That lets us set it all up in a single “connection” to InputBegan.
Example dash script using UserInputService
--Put in StarterPlayer.StarterCharacterScripts
local InputS = game:GetService("UserInputService")
local RunS = game:GetService("RunService")
local camera = game.Workspace.CurrentCamera
local c = script.Parent
local humanoid = c:WaitForChild("Humanoid")
local rootPart = c:WaitForChild("HumanoidRootPart")
local dashBodyVelocity = Instance.new("BodyVelocity")
dashBodyVelocity.Name = "DashBodyVelocity"
dashBodyVelocity.MaxForce = Vector3.new()
dashBodyVelocity.Velocity = Vector3.new()
dashBodyVelocity.Parent = rootPart
local dashSpeed = 50
local dashForce = 40000
InputS.InputBegan:Connect(function(inputObject)
if inputObject.KeyCode == Enum.KeyCode.Q or inputObject.KeyCode == Enum.KeyCode.E then
local dashDirection = inputObject.KeyCode == Enum.KeyCode.Q and -1 or 1
--Start dashing
dashBodyVelocity.Velocity = camera.CFrame.RightVector * dashSpeed * dashDirection
dashBodyVelocity.MaxForce = Vector3.new(1, 0, 1) * dashForce
local changedC --must be declared before assignment because otherwise it won't be visible to the connected funciton.
changedC = inputObject:GetPropertyChangedSignal("UserInputState"):Connect(function()
if inputObject.UserInputState == Enum.UserInputState.End then
changedC:Disconnect() --clean up the connection, otherwise it'd exist forever
--Stop dashing
dashBodyVelocity.Velocity = Vector3.new()
dashBodyVelocity.MaxForce = Vector3.new()
end
end)
end
end)
You can use ContextActionService to do all of this in a slightly shorter way, and I think it’s easier to understand too:
Example dash script with ContextActionService
local ActionS = game:GetService("ContextActionService")
local RunS = game:GetService("RunService")
local camera = game.Workspace.CurrentCamera
local c = script.Parent
local humanoid = c:WaitForChild("Humanoid")
local rootPart = c:WaitForChild("HumanoidRootPart")
local dashBodyVelocity = Instance.new("BodyVelocity")
dashBodyVelocity.Name = "DashBodyVelocity"
dashBodyVelocity.MaxForce = Vector3.new()
dashBodyVelocity.Velocity = Vector3.new()
dashBodyVelocity.Parent = rootPart
local dashSpeed = 50
local dashForce = 40000
function onDashInputChanged(actionName, inputState, inputObject)
if inputState == Enum.UserInputState.Begin then
local dashDirection = inputObject.KeyCode == Enum.KeyCode.Q and -1 or 1
--Start dashing
dashBodyVelocity.Velocity = camera.CFrame.RightVector * dashSpeed * dashDirection
dashBodyVelocity.MaxForce = Vector3.new(1, 0, 1) * dashForce
else --inputState = End
--Stop dashing
dashBodyVelocity.Velocity = Vector3.new()
dashBodyVelocity.MaxForce = Vector3.new()
end
end
ActionS:BindAction("dashRight", onDashInputChanged, false, Enum.KeyCode.Q, Enum.KeyCode.E)
CAS is great because you can easily overwrite the binding to do nothing when you’re in a different context, e.g. if the player opens a menu where you don’t want them to accidentally dash when pressing E.
So I can use your dash script example using UserInputService, and it will allow the player to move in the direction the player wants to move with lookVector? When I tried your script, it moved me to the side like side stepping,although i appreciate your effort in this, but that wasn’t what i wanted. The original script i had was to make the player dash while holding down E and whatever direction they want. Then again it my fault for not mentioning this.The problem I had was whenever hold down the E key it doesn’t let me stop moving my character, once I am done pressed down the E key.
edit: also how come theres a -1 or 1 in line 21 of the code for the example of the UserInputService?
This is a “trick” that uses the fact that if you multiply a direction represented by a vector by -1, you get a vector in the opposite direction. So instead of having an if-else statement where both execution paths are the same code repeated except for a * 1 or *-1, I just change the direction that the force is applied by multiplying it by either 1 (doing nothing) or -1 (flipping the direction).
Instead of having an if-else statement to set dashDirection, I use something like a “ternary” operator common in other programming languages. Lua doesn’t have that operator, but the same can be accomplished with the and and or logical operators. The effect is that if the Q key was pressed dashDirection is set to -1, otherwise it’s set to 1. If you want to know more about it, search for “Lua ternary”.
Sure, something like this should do the trick:
Code
--Put in StarterPlayer.StarterCharacterScripts
local InputS = game:GetService("UserInputService")
local RunS = game:GetService("RunService")
local camera = game.Workspace.CurrentCamera
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local dashBodyVelocity = Instance.new("BodyVelocity")
dashBodyVelocity.Name = "DashBodyVelocity"
dashBodyVelocity.MaxForce = Vector3.new()
dashBodyVelocity.Velocity = Vector3.new()
dashBodyVelocity.Parent = rootPart
local dashSpeed = 50
local dashForce = 40000
InputS.InputBegan:Connect(function(inputObject)
if inputObject.KeyCode == Enum.KeyCode.E then
--Start dashing
dashBodyVelocity.Velocity = camera.CFrame.LookVector * dashSpeed
dashBodyVelocity.MaxForce = Vector3.new(1, 0, 1) * dashForce
local changedC, renderSteppedC --must be declared before assignment because otherwise it won't be visible to the connected funciton.
--Stop dashing when dash key is released
changedC = inputObject:GetPropertyChangedSignal("UserInputState"):Connect(function()
if inputObject.UserInputState == Enum.UserInputState.End then
changedC:Disconnect() --clean up the connection, otherwise it'd exist forever
renderSteppedC:Disconnect() --stop updating the direction by disconnecting
--Stop dashing
dashBodyVelocity.Velocity = Vector3.new()
dashBodyVelocity.MaxForce = Vector3.new()
end
end)
--Update dash force direction every frame, otherwise player would just dash in one direction forever
renderSteppedC = RunService.RenderStepped:Connect(function()
dashBodyVelocity.Velocity = camera.CFrame.LookVector * dashSpeed
end)
end
end)