The reason I’m jumping is because that’s how vaulting works, if the player jump and finds a valid ledge. They will hop over it. My entire issue right now is that I don’t want a player hopping over a ledge IF there is a part right on top of it OR if there is a part too close to the top.
I’ve already provided examples in the “Clarification” tab in the original post.
I’ll attach a gif of what vaulting is SUPPOSED to look like.
Oh… well then you should be shooting a ray forward again (from; it looks like the top of his head…?), and/or a long enough diagonal ray to check for an overhang…
OK for World math problem; I calculate the start and end points of the ray fully; then do a LookAt to get the the CFrame angle to shoot.
-- Climb or Jump
if Hit and Hit ~= AItorso then
if (Hit.Name == "Truss" and target.Position.y > torsoPos.y - 3) or target.Parent == Hit.Parent then -- ignore parts called "Ladder", if AI is level or below CURRENT Targ pos.
Hit = nil
ClimbingLadder = true -- Climb and don't check floor
else
--print(Hit, Hit.Name)
if Hit.Name == "Terrain" or Hit.CanCollide == false then -- In front is Water or a steep hill made of Terrain.
Hit = nil -- swim or climb, or Ray hit a Non-colliding Part; and don't check for floor. This will not do, as we do not get a Hit when under-water, so we will check for floor. We must check Swimming event.
else -- Jump?
Hit = DrawRay(originPrime + Vector3.new(0,4.8,0), pointPrime)
if Hit == nil then -- (Does NOT check CanCollide of Part blocking Jump)
hum.Jump = true -- we do NOT check for "Floor", if jumping, but it might be a good idea.
end -- Room to jump?
end --Terrain? Water?
end -- Ladder?
else -- path is clear. Check for cliff... or OK to drop
TrueHeight still works even for rotated parts since it only accounts for the Y axis. On block shaped parts, the height is always the same no matter what.
As for the multiplication by the CFrame (assuming that’s what you’re talking about), I changed it a while back. But it was initially just to offset the origin forward so It would be inside the actual part instead of at the ray intersection point. I’ll update the code right now.
If you want to check if there is a part above the ledge part, why don’t you set the z origin of your current raycast, which is directly above the player, in front of the player?
Cause, by the gif provided it looks like the origin of the raycast is coming from the players head. Instead for the origin you could add in
NewRaycastOrigin * CFrame.new(0, 0, -2)
where -2 is the interchangeable amount and NewRaycast Origin is (wherever you are currently starting your raycast)
I think the ray is still on the outside of the part. For it to detect the part on top, I think it would have to be inside it. Right now, it is just of the edge of the part. https://gyazo.com/3e4b1dfe06b71808a53f4ba7a0075d1e
That is why in this gif, it detected the part on top top while the part on top was undetected
NewRaycastOrigin.Y is located at the top edge of a part (TrueHeight). The x and z cords of NewRaycastOrigin is the intersection point of the ray and the part. It isn’t actually in any way related to the player’s head.
I’ve tried to multiply NewRaycastOrigin by a new CFrame but it starts to point to a random coordinate in the world. (This is my biggest issue currently)
Although I could be misunderstanding what you’re saying, so please let me know if I am.
Yes… I know that. This is the problem I’ve been having this entire time…
For some reason I’m unable to change NewRaycastOrigin at all, since it points to a position in the world instead of offsetting the ray if I try to multiply it by a CFrame or add it to a Vector3.
I gave you the code, but not the input.
This is off the top of my head so it will contain errors
I assume that you shoot the ray at the top of his Jump
or something.
originPrime = Head.Positionn -- From Player's head
Up = Head.CFrame.UpVector
Forward = Head.CFrame.LookVector
pointPrime = originPrime + Up *5 + Forward * 2 -- To a point up and forwar from Player
Dist= (originPrime - pointPrime).magnitude
dir = CFrame.lookAt(originPrime, pointPrime) * Dist
Hit = DrawRay(originPrime, dir) -- Make sure that Player is blacklisted in your Drawray
if Hit == nil or (Hit and Hit.CanCollide == false) then -- Really, I guess you should add a non-collidable part to the blacklist and shoot ray again
hum.Jump = true
else
--don't
end -- Room to jump?
What if you used multiple raycasts in succession in the shape of an F or something?
Also just in case I missed something, why is it that players wouldn’t be able to vault over when the wall is stacked, given that its total height is still low enough to do so?
The player shouldn’t be allowed to vault over stacked walls even if the total height is still low enough because there are structures in my game that consist of multiple parts.
In this example, Part 2 (as indicated in red) is at height that can be vaulted over, however it actually makes up part of a wall. Therefore if you are allowed to vault over it, you would be able to reach the top of Part 3 due to the jump boost you get after vaulting. This wouldn’t work in my game because some areas are blocked off and should not be climbable. Although I could manually make these un-vaultable, this would take time and would heavily interrupt my work flow, so I’d prefer not to unless I have no other choice.
As for your F method, it’s quite a good idea and I like it, however there is a problem with it due to a (somewhat?) similar circumstance as mentioned in my door example. If there is some object in-between the two parts that is somehow missed by the raycast, it would allow the player to vault.
And although this could be mitigated if I raycast in the horizontal direction in smaller intervals so the rays would be closer together, this could still have the chance to miss very thin obstacles and could be computationally expensive if I do it too often and too fast.
About the stacked parts problem, you can easily check for the total height to prevent players from abusing the vault jump boost. With my proposed solution stated above, you can sum up the number of successful raycasts (the ones that hit something) to determine the height of the entire structure. For areas that are “unvaultable”, I would assume that you would use an invisible ceiling right beside the edge, which my method also conveniently checks with the vertical raycast that shoots directly up above the player’s head.
As far as I know, raycasts are pretty optimized nowadays. I’ve made a few projects in the past that uses raycasts extensively and through my experience, it really only causes performance issues if you’re raycasting hundreds of times per frame. So I doubt increasing the number of raycasts to improve accuracy would pose any performance issues; the increment can be as low as 0.1 studs or even smaller no problem. And on top of that, these are mostly really short raycasts which would benefit the performance even further.
If you’re still concerned with small parts being undetected by the wall of raycasts, you can complicate things even further by also using spatial queries (basically Region3 functions but better) to check for parts inside the allegedly open pathway that the raycasts found.
Hm, yea it seems like it could definitely work. However, I am concerned about some really weird edge cases I may come across. For example:
If the vertical raycast hits an object as it’s fired from the Player’s head, it could mess up the the total height and return data that isn’t accurate. Now you may consider this a stretch or just me being paranoid, but there a lot of things that I feel could be easily solved if I just fired a single raycast directly from the top edge off the vaultable part.
In that kind of scenario, the ceiling would be used to cap off the size of the opening. Think of it as this statement:
--if there is no ceiling, then the highestRaycastHeight is used as the upper-bound as usual
openingSize = (ceilingHeight and (ceilingHeight < highestRaycastHeight and ceilingHeight) or highestRaycastHeight) - lowestRaycastHeight
If the player can still fit through the restricted pathway, they can vault over. Otherwise, they just realistically can’t.
For blockages that go a bit deeper into the opening, you can make the horizontal raycasts a bit longer to hopefully detect those, or you can always fall back on the spatial query solution.
Yea I guess that makes more sense, I’m still going to keep trying to make it work using only one ray, however if I can’t figure it out, I’ll just use your method.
Then your DrawRay function doesn’t work.
You can’t shoot one Ray from origin to a point in front of the Player?
Use the DrawRay function i gave, and calculate the start and end points like I did. Then use LookAt to get a direction.
Don’t use the Parts you hit for any calculations…
The graphics will show you where you are shooting the ray and weather you hit or not… A short black, fat line if you hit; a long, thin, white line if you didn’t…
In front of Player is CFrame.LookVector Above is CFrame.UpVector, Add them to the Origin to get a Point to LookAt. Then multiply Direction * distance to get the Ray’s Direction input. Put Print statements to make sure that you are getting the right numbers.
This is a standard CanIjump ray. At least get that going first; then fine-tune it.
You can shoot more: Shoot a ray, from the Point that you calculated, straight down (Vectore.new(0,-1,0) to find-out if there is a floor in front of you too…
I’ve shot rays in front of Birds, Spiders and Zombies to always know what is in front of me…