Whenever I am nearby to a wall or object, and facing it, the ray always exists and the mover velocity is set
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?
Oh yea, I completely missed that. It works now, the only problem is that it pushes me away from the wall when I am within distance, not towards
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?
You’d just have to subtract that by the distance, and make sure it doesn’t go negative, to prevent knockback.
local Distance = result.Distance - 0.1
Distance = if Distance < 0 then 0 else Distance -- 0 magnitude if too close.
mover.Velocity = 4 * Distance * velocity.Unit
I’d wonder however, about the precision of that 0.25 Debris timer.
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
.
local result = workspace:Raycast(parent.Position, velocity.Unit / 4, raycastParams)
Correct? Seems to be working well, however, when really closeby it’s a bit weird
PS: I’ve adjusted this line, just incase you were wondering. Although it shouldn’t effect anything
local Distance = result.Distance - 1.5 (vs 0.1)
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.
Yea I was thinking about that too, idk how’d I do that. For some reason, ever since changing this line to velocity.Unit / 4, result always prints nil
local result = workspace:Raycast(parent.Position, velocity.Unit / 4, raycastParams)
print(result)
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
.
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:
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.
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.