I have a body velocity that pushes a player forwards very quickly, I’m looking for a way to stop player’s getting flung into walls, and I’d like them to stop just before the wall. One method I tried, that was a bit messy, was raycasting and detecting the wall, then setting the velocity to the distance, but it continues to fling players.
function module:CreateMover(parent, velocity)
task.spawn(function()
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 distance, hit = workspace:Raycast(parent.Position, velocity, raycastParams)
if hit then
mover.Velocity = distance
end
mover.Velocity = velocity
mover.Parent = parent
game.Debris:AddItem(mover, 0.25)
end)
end
In this script, parent is always the player’s HumanoidRootPart, and the velocity is Humanoid.MoveDirection if they are moving, and CFrame.LookVector if stationary
Also, I am aware that BodyVelocity is deprecated, but I’m using it for now as LinearVelocity and VectorForces were causing me pain
Something to note, is that the return of workspace:Raycast(), (assuming it hits something) is a single RaycastResult object (this isn’t a tuple, it’s its own datatype where Distance and Instance are properties.). That’s what will be assigned to distance; therefore hit will always be set to nil (which is treated as falsy, so your if-statement will never pass).
local result = workspace:Raycast(parent.Position, velocity, raycastParams)
if result ~= nil then
if result.Instance ~= nil then
mover.Velocity = (parent.Position - result.Position)
end
end
However, it’s still glitchy when going up close
I’m also looking for a way to prevent them from ragdolling when zooming up this ramp
Something I find interesting about that code, is that subtracting the point of intersection, from the player’s position, should always result in a vector going in the opposite direction. Yet in your video, we still see the character moving towards the collision, rather than away. Is it possible the Raycast isn’t actually hitting? Perhaps consider doing some print debugging to make sure the code is actually following the paths you expect it to.
Are you unintentionally resetting the BodyMover’s Velocity to the velocity variable before you Parent it, regardless of your hit check (as in your original code)? Otherwise, is it possible there may be multiple forces at work?
Progress! That’s the expected logic based on your math. The problem now is calculating the appropriate velocity for 0.25 seconds worth movement, based on that distance.
I’m making an assumption that BodyVelocity’s Velocity property lines up to 1 stud per second, but if so, perhaps mover.Velocity = distance/4 * velocity.Unit
Moving in the correct direction, but not by the correct amount! It is only moving every so slightly forwards
local result = workspace:Raycast(parent.Position, velocity, raycastParams)
if result ~= nil then
if result.Instance ~= nil then
mover.Velocity = result.Distance / 4 * velocity.Unit
else
mover.Velocity = velocity
end
else
mover.Velocity = velocity
end
```
Ah. Of course. Since it’s only 0.25 seconds of movement, the magnitude should really be *4 to compensate, and not /4. Try 4 * result.Distance * velocity.Unit
That’s what I was thinking. It works I believe, however I do still get flung when I hit the wall, so how would I be able to stop just in front of the wall, let’s say 0.1 studs?
Something seems off. It almost looks like it’s moving too fast, or maybe that’s just my eyes. It also appears that it casts a ray when it really doesn’t look like it is going to hit the wall, perhaps something with the ray length?
So the length of the ray is going to be the magnitude of the direction vector you fed to Raycast. So in your case, that’s going to be the magnitude of the velocity variable. Since it appears that the rate of BodyMover.Velocity does indeed line up with studs per second, and you’re only moving for a quarter of a second, you’d really only want to raycast a 4th of that distance (since that’s how far you’d actually be traveling). So velocity.Unit/4.
So I’m thinking, that you’d really want to stop half a stud back, since the position of parent (presumably the torso?) is within the center of the part, and not the surface of the part, where we’d want to be doing this distance calculation from.
Yea, but the issue in the video is still there where it doesn’t stop a half stud back when closer to the part. Perhaps I could just cancel the BodyVelocity if it’s that close to a wall
That would be a solution, but then you also wouldn’t move on any inclines that trip the ray. Though moving over inclines is really its own challenge in of itself, since I’d imagine you’d want to be moving in a direction parallel to the surface, rather than into it.