Raycast; Alternatives to LookVector?

Hi Guys!

I am using a standard dashing script that allows the player to dash in all directions.

I also using RayCasting in my game to latch players to nearby objects.

I want to put this latching function inside of my dash code, and at first glance it works fine.

However, my dash code is more free? than other dashs, it uses BodyVelocity so the player can dash up if they wanted to.

So whenever the latch function plays, there a chance for the player to latch into the ground like this:
https://gyazo.com/5c461724aa8dfc05344591de23aa8025

Otherwise if the player doesn’t latch into the ground it works great!
https://gyazo.com/53bb24040166256a1f722c9808ecb9c4?token=d9d091c8a1adb54d017036cd4ea82661

I guess that I am basically making this post because I am unsure if I would be able to Raycast strictly forward. I believe that LookVector already does this and I am unsure if there is a way for me to get around this issue. I am not sure if using CFrame.Z would make any difference, so I am just asking for opinions.

If anyone can give me any insight then that’ll be great!

1 Like

I think what you may be asking is how to flatten onto the xz plane while keeping the vector at a length of 1 (a unit vector).

I often use this code:

local vec = humanoidRootPart.CFrame.lookVector -- or use camera.CoordinateFrame.lookVector
local flatVec = vec * Vector3.new(1,0,1) -- Doesn't have a length of 1
local flatVecUnit = flatVec.unit -- Does have a length of 1
-- The check below is necessary to make sure that the vector didn't get corrupt when being unitized.
if flatVecUnit.x ~= flatVecUnit.x then flatVecUnit = Vector3.new(0,0,-1) end


2 Likes

I will definitely try this if my current method ends up not being possible.

Basically I already started to try and cast the direction of Ray into local space, but I am not sure how to do it.

I know CFrame:ToWorldSpace() does what I want, but its for CFrames.

local origin = HRP.Position + Vector3.new(0,2,0)
local direction = HRP.CFrame.LookVector * Vector3.new(0,0,20)

Would there be a way to make the Vector3 direction local to the player?

As of now the code is in global context and always casts on the game’s Z axis instead of players.

1 Like
local origin = HRP.Position + Vector3.new(0,2,0)
local direction = HRP.CFrame.LookVector * 20 + HRP.Position

Should work fine

1 Like

This seems to fling the player across the map now

https://gyazo.com/b753fc0f3ce027be300c4442216b46ab

https://gyazo.com/8e47bb51e1ef701276242d220ef0da55?token=d255b11a16c57f3aca83567a6c194c24

1 Like

Do you want the raycast to go where the HumanoidRootPart is facing or where the camera is facing?

1 Like

I want the raycast to be in front of the player.

Always towards the direction they are walking.

The code I currently have with local direction = HRP.CFrame.LookVector allows the player to latch into the ground, and thats what I am trying to fix.

1 Like

Testing the variable I gave you should work fine:
Screenshot_2666
(The part is where the Direction Vector3 is)

Code I used to test
local Player = game.Players.LocalPlayer

repeat wait() until Player.Character

wait(10)

local HRP = Player.Character.HumanoidRootPart
local Pos = HRP.CFrame.LookVector * 20 + HRP.Position
local Part = Instance.new("Part")
Part.Size = Vector3.new(1,1,1)
Part.Anchored = true
Part.Position = Pos
Part.Parent = workspace

Could I see your script?

1 Like

This is code that I change using your variable: – Probably the only one you have to look at

Summary
function forwardlatch()													-- Is is possible to get the direction locally
	
	local origin = HRP.Position + Vector3.new(0,2,0)
	local direction = HRP.CFrame.LookVector * 20 + HRP.Position

	local result = Workspace:Raycast(origin, direction, rayParams)
	if result then
		latchvalue = true
		results = result.Normal
		pos = result.Position
		typ = result.Instance
		pcframe = CFrame.new(pos)
		SurfaceCFrame = CFrame.new(result.Position, result.Position+result.Normal)*CFrame.Angles(math.rad(-90),85,0)
	end
	
	if results == nil then
		latchvalue = false
		return
	end

	if results ~= nil then
		print("normal latching began")
		latching()
	end
	
end

Inside of that code ^; the latching() function is called, this is it:

Summary
function latching()		
	
	print(latchvalue)
	latchingToWall = results
	if typ == workspace.Terrain then
		print("Latching to Terrain")
		HRP.CFrame = SurfaceCFrame:ToWorldSpace(pOffset)		
	else
		HRP.CFrame = pcframe
	end											
	wait(.1)
	latchingToWall = nil
	results = nil
	pos = nil
	pcframe = nil
	typ = nil
	SurfaceCFrame = nil
	latchvalue = false

end

And then this is the dash function, where the forwardlatch() function is called:

Summary
local Tapped = false
local DoubleTapTime = 0.2
local CoolDown = 1.5

local LastTime = tick()
local LastTime2 = tick()
local LastTime3 = tick()
local LastTime4 = tick()

local DB = false
local Dashing = false
UIS.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode == Enum.KeyCode.W then
		local now = tick()
		local difference = (now - LastTime)

		if difference <= DoubleTapTime and not DB then 
			delay(.4, function()
				Dashing = false
			end)

			local BV = Instance.new("BodyVelocity", character.PrimaryPart)
			BV.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
			BV.Velocity = Vector3.new(0,0,0)
			BV.Name = "DashForce"
			
			Dashing = true
			

			local latchcon
			latchcon = RunService.Heartbeat:Connect(function()
				if Dashing then
					forwardlatch()
				else
					latchcon:Disconnect()
				end
			end)
			
			local Connection
			
			Connection = game:GetService('RunService').Heartbeat:Connect(function()
				local Suc, Err = pcall(function()
					if Dashing == true then
						DB = true
						BV.Velocity = Cam.CFrame.lookVector * 75
						
						local Gravity = Controller.GravityUp
						if (Gravity-Vector3.new(0, 1, 0)).Magnitude > .1 then
							Dashing = false
						end	
						
					elseif Dashing == false then
						Connection:Disconnect()
						BV:Destroy()
						wait(CoolDown)
						DB = false
						Dashing = false
					end
				end)
				if not Suc and Err then
					print(Err)
					Connection:Disconnect()
				end
			end)
		end
		LastTime = tick()
        end
end)

Sorry if it’s confusing, I use the latch functions in a lot of other functions so this simplifies it for me.

1 Like

I believe the problem is in the origin variable due to the + Vector3.new(0,2,0) causes the ray to not be straight:

Screenshot_2667

You could fix this by either removing the + Vector3.new(0,2,0) or changing the direction variable to:

local direction = HRP.CFrame.LookVector * 20 + HRP.Position + Vector3.new(0,2,0)
1 Like

I removed + Vector3.new(0,2,0) so this is what I have now:

	local origin = HRP.Position
	local direction = HRP.CFrame.LookVector * 20 + HRP.Position

It seems that the ray is casting on Global still and + HRP.Position seems to be the cause of it.

In this GIF I am trying to latch to the wall in front of me, but it instead moves me far away to the side.
https://gyazo.com/a6bac2fef29380e42dececa750f2c7a3

Another GIF of just dashing in the open:
https://gyazo.com/c823ba611a898aa2fd22c1da0eae2e77

1 Like

Here is a function I used for debugging once:

local function CreateVisualRay(Origin,Direction)
	local RayPart = Instance.new("Part")
	RayPart.Material = Enum.Material.Neon
	RayPart.BrickColor = BrickColor.new("New Yeller")
	RayPart.Anchored = true
	RayPart.CanCollide = false
	
	local Size = (Origin - Direction).Magnitude
	RayPart.Size = Vector3.new(0.1, 0.1, Direction.magnitude)
	
	local MidPoint = Origin + Direction/2
	RayPart.CFrame = CFrame.new(MidPoint, Origin)
	RayPart.Parent = workspace
end

This will make the ray visible, could you implement it somewhere temporarily and upload a picture?

1 Like

What you can do is insert a bodyvelocity into the hrp, and then set the velocity to the direction; then you delete it after .2 seconds or something.

This might help you:

1 Like

Yes this is actually how my dash function runs:

Summary
if difference <= DoubleTapTime and not DB then 
			delay(.4, function()
				Dashing = false
			end)

			local BV = Instance.new("BodyVelocity", character.PrimaryPart)
			BV.MaxForce = Vector3.new(math.huge,math.huge,math.huge)
			BV.Velocity = Vector3.new(0,0,0)
			BV.Name = "DashForce"
			
			Dashing = true
			

			local latchcon
			latchcon = RunService.Heartbeat:Connect(function()
				if Dashing then
					forwardlatch()
				else
					latchcon:Disconnect()
				end
			end)
			
			local Connection
			
			Connection = game:GetService('RunService').Heartbeat:Connect(function()
				local Suc, Err = pcall(function()
					if Dashing == true then
						DB = true
						BV.Velocity = Cam.CFrame.lookVector * 75
						
						local Gravity = Controller.GravityUp
						if (Gravity-Vector3.new(0, 1, 0)).Magnitude > .1 then
							Dashing = false
						end	
						
					elseif Dashing == false then
						Connection:Disconnect()
						BV:Destroy()
						wait(CoolDown)
						DB = false
						Dashing = false
					end
				end)
				if not Suc and Err then
					print(Err)
					Connection:Disconnect()
				end
			end)
		end
1 Like

I am definitely pretty new to scripting so I don’t really understand anything I make fully

That said, can you tell me why you added + HRP.Position and what that does exactly?

It seems to me that it’s casting 20 studs out of the LookVector, but then I am not sure how to + HRP.Position changes this.

EDIT:

As a side note;

I feel like the best way to achieve what I want to happen, would be to limit the lookVector to be flat, as @VitalWinter suggested. However, I am unsure of how to incorporate that into the code I already have.

1 Like

Hmm I am not too sure what the + HRP.Position does either but it seems to work for parts (without it it doesn’t), perhaps try removing it for the raycasting.
If it works that way I’m not sure why it is different.

1 Like

The function works without + HRP.Position but it still has the issue where the player gets stuck into the ground.

I would imagine that it is something that can only be used with parts?

1 Like

I’ve seemed to have figure out how to resolve me issue thanks to @VitalWinter

Here is the ending code:

Summary
function forwardlatch()													-- Is is possible to get the direction locally
	
	local origin = HRP.Position
	local vec = HRP.CFrame.LookVector
	local flatvec = vec * Vector3.new(1,0,1)
	local direction = flatvec * 20 

	local result = Workspace:Raycast(origin, direction, rayParams)
	if result then
		latchvalue = true
		results = result.Normal
		pos = result.Position
		typ = result.Instance
		pcframe = CFrame.new(pos)
		SurfaceCFrame = CFrame.new(result.Position, result.Position+result.Normal)*CFrame.Angles(math.rad(-90),85,0)
	end
	
	if results == nil then
		latchvalue = false
                return
	end

	if results ~= nil then
		print("normal latching began")
		latching()
	end
	
end

I had to limit the Raycast direction to only the X and Y axis.

I did this with VitalWinter’s code and his help by including this code:

 local origin = HRP.Position
	local vec = HRP.CFrame.LookVector
	local flatvec = vec * Vector3.new(1,0,1)
	local direction = flatvec * 20 
3 Likes