How to stop bodyvelocity causing player to fling on contact with wall

Right. My 3AM math mind is making all kinds of mistakes tonight. I don’t know why I normalized it with .Unit; we still need to account for its magnitude. Try simply velocity/4.

1 Like

Awesome, everything works well now. Here is the final script

local mover = Instance.new("BodyVelocity") -- move the person being hit
		mover.MaxForce = Vector3.new(9e99, 9e99, 9e99)
		
		local raycastParams = RaycastParams.new()
		raycastParams.FilterType = Enum.RaycastFilterType.Exclude
		raycastParams.FilterDescendantsInstances = {parent}
		
		local result = workspace:Raycast(parent.Position, velocity / 4, raycastParams)
		if result ~= nil then
			if result.Instance ~= nil then
				print(result.Distance)
				
				local Distance = result.Distance - 1.5
				Distance = if Distance < 0 then 0 else Distance -- 0 magnitude if too close.
				mover.Velocity = 4 * Distance * velocity.Unit
			else
				mover.Velocity = velocity
			end
		else
			mover.Velocity = velocity
		end
		
		mover.Parent = parent
		game.Debris:AddItem(mover, 0.25)

Regarding getting up slopes, I would need to adjust the velocity var to account for the slope, correct?. Currently the velocity argument is the move direction of the character Any idea how I could achieve something like that?

So here’s what I’m thinking for your slope problem:
image
You can use the Normal returned from your original raycast to generate a new position off of the surface, then calculate the direction between the origin and that point, and use that as the new velocity. And since you can always expect the Y portion of the original movement direction to otherwise be about 0, you can subtract that from the Y value of the normal, in order to gauge whether the intersection is sloped to begin with.

Something like

local CharacterHeight = 2.5
if (result.Normal.Y - velocity.Unit.Y) > 0.5 then -- Determine if hit is sloped enough not to just be treated as a wall
	local CastedPoint = result.Position + result.Normal * ChacterHeight -- Calculate a point from the surface normal, out the character's height
	local NewDirection = (CastedPoint - parent.Position).Unit * Velocity.Magnitude -- Obtain the new direction, and set it to our old direction's magnitude
end

The only problem, that you’d likely then have to send a second raycast using that new direction, in order to validate that there won’t be any obstacles jutting out from the surface of the slope, that you may need to stop short of.

1 Like

Update, I just used this script, and it solves all problems with the flinging into walls, and even works going up a slope!

mover.MaxForce = Vector3.new(1, 0, 1) * 14000
mover.Velocity = hrp.CFrame.LookVector * 100

for i = 1, 8 do
	task.wait(0.1)
	mover.Velocity *= 0.7
end

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