How to stop body Velocity when the player collides with a wall or something else

I have a dash system that is based on bodyVelocity, I have a problem that if a player collides with a wall or something else, he will either push off from it or pass through(or is the player just shaking). Does anyone know how to solve this problem?

local function dashFunction(direction, dashStartSpeed, dashDuration, dashEndSpeed,Evade)
	local Players = game:GetService("Players")
	local Player = Players.LocalPlayer
	local Character = Player.Character or Player.CharacterAdded:Wait()
	local HRP = Character:FindFirstChild("HumanoidRootPart")
	local Humanoid = Character:FindFirstChildOfClass("Humanoid")

	local increment = ((dashEndSpeed- dashStartSpeed) / (dashDuration* 60)) * 2 
	local BodyVelocity = Instance.new("BodyVelocity", HRP)
	BVToRemove = BodyVelocity
	BodyVelocity.MaxForce = Vector3.new(math.huge,0,math.huge)
	if direction == "right" or direction == "left" then
	 gameSettings.RotationType = Enum.RotationType.CameraRelative
	end

	local directionalForce
	if direction == "forward" or direction == "right" then
		directionalForce = 1
	elseif direction == "backward" or direction == "left" or direction == "knockback" then
		directionalForce = -1
	end
	DashRemote:FireServer({DashDirection = direction, Evade = false, message = "Sound"})
	
	for i=dashStartSpeed,dashEndSpeed,increment do
		if direction == "forward" or direction == "backward" or direction == "knockback" then
			local MoveDirection = HRP.CFrame.LookVector
			if Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.FallingDown then
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce) / 1.25 -- So that you dash less further in air
				wait()
			else 
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce)
				wait()
			end
		elseif direction == "left" or direction == "right" then
			local MoveDirection = HRP.CFrame.RightVector
			if Humanoid:GetState() == Enum.HumanoidStateType.Jumping or Humanoid:GetState() == Enum.HumanoidStateType.Freefall or Humanoid:GetState() == Enum.HumanoidStateType.FallingDown then
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce) / 1.25 -- So that you dash less further in air
				wait()
			else 
				BodyVelocity.Velocity = Vector3.new(MoveDirection.X * i * directionalForce, 0, MoveDirection.Z * i * directionalForce)
				wait()
			end
		end
	end
	
	canContinue = true
	if Evade then
		canContinueEvade = true
	end
	local suc,err = pcall(function()
	BodyVelocity:Destroy()
	end)
	AnimSave:AdjustSpeed(1)
	DashRemote:FireServer({Type = "Remove", DashDirection = direction, Evade = false, message = "Attribute"})
	gameSettings.RotationType = Enum.RotationType.MovementRelative
end

I think raycast could help me, but I do not know how to install it correctly for my system.

Problem

2 Likes

Just stop the dash when the HumanoidRootPart collides with anything that isn’t a descendant of the character.

Hi, thanks for the reply. I tried your suggestion and it got even worse, the player is now being thrown a very long distance or thrown up. And also, the player can still walk through the wall while dashing.

Does the wall have CanCollide off?

And after the dash ends you need to make sure their velocity in the direction they dashed is reset.

Can you provide the modified script?

Have you tried creating a raycast from the players head, if the ray hits a part then stop the velocity.

1 Like

here are the added lines of code

HRP.Touched:Connect(function(hit)
	if not canContinue then
		if hit:HasTag("Wall") then
			BVToRemove.Velocity = Vector3.zero
			BVToRemove.MaxForce = Vector3.zero
			BVToRemove:Destroy()
		end
	end
end)

ā€œnot canContinueā€ is just a check that dash is active

as I said before, I was thinking about raycast, but I didn’t know how to use it properly in my function.

You need to remove the velocity after the dash ends.

My system just deletes bodyVelocity after a certain time, so I have no idea how I should remove the speed at the end of the dash.

  1. You’re using an old body mover. LinearVelocity would be better for this
  2. Raycast :+1:
  3. You should probably use task.wait instead of wait

I’m using bodyVelocity because I’m already used to it, I’m not going to switch yet.

I get being used to things, but I would strongly suggest it for anything you do in the future. There’s a reason it’s depricated.

Not sure what you mean by ā€˜use properly in my function’ - raycast functions the same everywhere. As per the Roblox API:

  • Set the Ray Origin (Position which the ray is being casted from, in your case the HRP or head) local headPosition = Character.Head.Position

  • Set the Ray Direction, this is where Raycast becomes superior to .Touched, you can stop your BodyVelocity before making contact with a BasePart to avoid glitches such as flinging. local headDirection = Character.Head.CFrame.LookVector * 3

  • Set the Raycast Result. local headResult = workspace:Raycast(headPosition, headDirection, Params)

if dashing and headResult and headResult.Instance then

-- Ray hit an Instance, stop BodyVelocity

end
1 Like

This would need to be in a PreSimulation (Stepped connection) to work properly 100% of the time

I’m sorry, I probably expressed my thought incorrectly, in general, I meant that I don’t know how to use raycast correctly to get the desired effect, I’ll read the documentation, but I’m not quite sure if I’ll be able to do everything right.

I understand, but I don’t plan to switch at the moment.

Not necessarily, that’s quite inefficient considering he is not dashing on RenderStepped. Assuming he’s using UIS or some sort to handle dashing, just have the raycast detection fired after the player dashes then disconnect it to prevent any potentional performance issues.

RenderStep should only be used for visuals. Regarding the inefficient performance, I wasn’t saying that there should always be a loop running, rather that you connect to PreSimulation when the dash starts and disconnect it when it ends.

Pre simulation runs before the physics simulation, so you can disable the force before the player crashes into the wall

P.S. if you only raycast once then you can’t actually prevent them from crashing into the wall if they change directions

Yes, it works, but not quite, why is it that when I do forward dash, raycast works properly and immediately, but if I do side dash or back dash, then raycast does not work correctly

Are you rotating the vector correctly?

1 Like