I created a teleportation system using Raycasting.
I use result.Position to get the position of the hit, and then CFrame.new(pos) to get the CFrame of the position.
I then teleport the player to that position by simply doing HRP.CFrame = pcframe.
It works great when the player teleports to an object that is a part! However if the Raycasting hits Terrain, then the Player seems to teleport inside of the Terrain.
EDIT: I am jumping off the part to reset, but I am falling off of the Terrain
I am not sure if I cannot teleport using CFrame for Terrain, or if there is an issue with my code, but I pretty much included all of the code included in this function above in the explaination.
If someone can get me on the right track or link me a similiar issue, that’ll be great!
Right well I may not understand how Terrain works correctly when saying this;
But from the Terrain GIF, it seems like its teleporting a little bit inside of the Terrain instead of the Surface.
You can see that the characters legs are inside of the wall, and then are pushed out. I think that may be why the player cannot stay on the wall after.
But like I said I may be wrong about that, and either way I could probably fix it my offsetting as suggested.
My theory is that a terrain’s collision is more complex than parts, and thats probably why. Parts that are hit are usually 1 surface where the player would hit, so the 1 surface would “nudge” the player. But for terrain there’s probably multiple collision surfaces the player is hitting, causing the force to cancel out or something like that, and/or the terrain’s collision is slightly lower than what the terrain visually is (makes sense in that term).
I do not believe that I can simply using HRP.CFrame = pcframe + Vector3.new(3,0,0) as this would move the player to a different location depending on where they are and which direction they are teleporting in.
I would have to use CFrame:ToWorldSpace()? Or is there another way that I am not realizing that I can use?
you can get the exact CFrame of the surface by doing this:
local SurfaceCFrame = CFrame.new(Result.Position, Result.Position+Result.Normal)*CFrame.Angles(math.rad(-90),0,0)
local OffsetPosition = SurfaceCFrame:PointToWorldSpace(Vector3.new(0,3,0))
basically you find the CFrame of the exact surface, and get a position Vector3 version of :ToWorldSpace() to offset it by 3 studs. Offsetting by local space is probably better than world space.