hi, hows yall doing, so i was coding a script that allows player to slowly fall when they hold space key in the freefall state the problem is
first
code only works if both conditions meet
what i want is to make if player is holding a space key while is in the air then fires this code
if he doesnt hold a key in air then doesnt do
second
How do i make player under linearVelocity still be able to move
here is the code
local UserInputService = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local rootAttachment = rootPart:WaitForChild("RootAttachment")
local linearVelocity: LinearVelocity = nil
local inputEndedConnection: RBXScriptConnection? = nil
local function release()
if linearVelocity ~= nil then
linearVelocity:Destroy()
linearVelocity = nil
end
if inputEndedConnection ~= nil then
inputEndedConnection:Disconnect()
inputEndedConnection = nil
end
end
humanoid.StateChanged:Connect(function(old, new)
if new == Enum.HumanoidStateType.Freefall then
task.wait(0.2) -- this wait is only way to sorta make it work
if UserInputService:IsKeyDown(Enum.KeyCode.Space) then
if inputEndedConnection == nil then
inputEndedConnection = UserInputService.InputEnded:Connect(function(input, gameProcessed)
if input.KeyCode == Enum.KeyCode.Space then
release()
end
end)
end
if linearVelocity == nil then
linearVelocity = Instance.new("LinearVelocity")
assert(linearVelocity ~= nil)
linearVelocity.Name = "SlowFallingVelocity"
linearVelocity.Attachment0 = rootAttachment
linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
linearVelocity.MaxForce = math.huge
linearVelocity.VectorVelocity = Vector3.new(0, -5, 0)
linearVelocity.Parent = rootPart
end
elseif new == Enum.HumanoidStateType.Running or new == Enum.HumanoidStateType.Landed then
release()
end
end
end)
at very least script does the job when it comes to player lands to the ground and linearVelocity getting destroyed and when player no longer hold a space key
A good way to do is to see when the player holds space using UserInputService.InputBegan/Ended and then use Humanoid:GetState() to see the state. This may fix the first issue.
And to make the player still move while falling, you need to use VectorForces, rather than using velocity.
Glad to see my code from before is still working and proved to be useful haha.
As @awry_y has said, connecting to the InputBegan signal is your solution here. We also keep the existing event but turn the creation of the LinearVelocity into its own function so we have 2 conditions without copy pasting code.
As for your LinearVelocity issue, you can set the ForceLimitMode to Enum.ForceLimitMode.PerAxis and change the MaxAxesForce to Vector3.new(0, math.huge, 0). This means that the LinearVelocity will have no affect on the X and Z axes and can apply as much force as it needs to on the Y axis.
The solution is a little bit tricky. Unfortunately, the Enum.HumanoidStateType.Freefall state runs almost immediately after the Enum.HumanoidStateType.Jumping state, meaning it does bug out at the start of the jump. I’ve implemented a workaround by creating a thread that:
Waits until the Humanoid state is Enum.HumanoidStateType.Freefall and the HumanoidRootPart’s AssemblyLinearVelocity.Y is less than 0.
Attaches the slow falling LinearVelocity.
This allows us to cancel the check and the creation with a simple task.cancel(thread) call.
Here is a working version that is not strictly typed:
local UserInputService = game:GetService("UserInputService")
local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local rootAttachment = rootPart:WaitForChild("RootAttachment")
local linearVelocity = nil
local inputEndedConnection = nil
local waitForCanSlowFallThread = nil
local function release()
if linearVelocity ~= nil then
print("destroyed linear velocity")
linearVelocity:Destroy()
linearVelocity = nil
end
if inputEndedConnection ~= nil then
inputEndedConnection:Disconnect()
inputEndedConnection = nil
end
if waitForCanSlowFallThread ~= nil then
task.cancel(waitForCanSlowFallThread)
waitForCanSlowFallThread = nil
end
end
local function attach()
if inputEndedConnection == nil then
inputEndedConnection = UserInputService.InputEnded:Connect(function(input, gameProcessed)
if input.KeyCode == Enum.KeyCode.Space then
release()
end
end)
end
waitForCanSlowFallThread = task.spawn(function()
while not (humanoid:GetState() == Enum.HumanoidStateType.Freefall and rootPart.AssemblyLinearVelocity.Y < 0) do
task.wait()
end
if linearVelocity == nil then
linearVelocity = Instance.new("LinearVelocity")
linearVelocity.Name = "SlowFallingVelocity"
linearVelocity.Attachment0 = rootAttachment
linearVelocity.RelativeTo = Enum.ActuatorRelativeTo.World
linearVelocity.ForceLimitMode = Enum.ForceLimitMode.PerAxis
linearVelocity.MaxAxesForce = Vector3.new(0, math.huge, 0)
linearVelocity.VectorVelocity = Vector3.new(0, -5, 0)
linearVelocity.Parent = rootPart
print("attached linear velocity")
end
end)
end
humanoid.StateChanged:Connect(function(old, new)
if new == Enum.HumanoidStateType.Freefall then
if UserInputService:IsKeyDown(Enum.KeyCode.Space) then
attach()
else
release()
end
elseif new == Enum.HumanoidStateType.Running or new == Enum.HumanoidStateType.Landed then
release()
end
end)
UserInputService.InputBegan:Connect(function(input, gameProcessedEvent)
if gameProcessedEvent then return end
if input.KeyCode == Enum.KeyCode.Space and humanoid:GetState() == Enum.HumanoidStateType.Freefall then
attach()
end
end)
Note:
I removed the assert(linearVelocity ~= nil) line as it is only used to bypass strict warning.