ScreenPointToRay not working with new ray

I have been trying to make the a laser gun with ScreenPointToRay and the new workspace:Raycast which I find more difficult than the old one. The old one is working fine but the new one just makes the laser beam go around 0,0,0 on the workspace. Which I can not understand why I tried changing the around the position, direction, and origin but it still won’t work. Any help would be appreciated.

-- Local Script
local CrossFrame = script.Parent.Crosshair.CrossFrame
local CrossHair = script.Parent.Crosshair
local ShotEvent = game.ReplicatedStorage.RE:WaitForChild("Bullet")
local ActivateShot = game.ReplicatedStorage.RE:WaitForChild("ActivateShot")
local RunService = game:GetService("RunService")
local clicked = false
local camera = game.Workspace.CurrentCamera

ActivateShot.OnClientEvent:Connect(function(player)
local length = 250
local middleof_screen = (CrossFrame.AbsolutePosition* 2)/2				
local crosshair_fireX = math.random(CrossFrame.AbsoluteSize.X) 
	  local crosshair_fireY = math.random(CrossFrame.AbsoluteSize.Y) 
		local unitray = camera:ScreenPointToRay(middleof_screen.X + crosshair_fireX, middleof_screen.Y + crosshair_fireY)
		local gravity_Ray = 313--[[196 + length]]
	local get_distance =  (unitray.Origin - unitray.Direction).Magnitude 
	local divise_distance = math.ceil(get_distance + gravity_Ray)
	--print(divise_distance)
	local speed =  800 + divise_distance
	UserInput.MouseIconEnabled = false
	if not clicked then
		CrossHair.Size = UDim2.new(0.085, 0, 0.085, 0)
	elseif clicked then
		CrossHair.Size = UDim2.new(0.070, 0, 0.070, 0)
	end
	ShotEvent:FireServer(length, unitray, camera, unitray.Direction * speed)	
	wait(.01)
	if not clicked then
		CrossHair.Size = UDim2.new(0.058, 0, 0.058, 0)
	elseif clicked then
		CrossHair.Size = UDim2.new(0.048, 0, 0.048, 0)
	end
	UserInput.MouseIconEnabled = false
end)
-- ServerScript
local Tool = script.Parent
local Handle = Tool.Handle
local Tip = Handle.Tip
local Event = Tool:WaitForChild("RemoteEvent")
local HandleAdornment = game.ReplicatedStorage:WaitForChild("CylinderHandleAdornment")
local RunService = game:GetService("RunService")
Debris = game:GetService("Debris")
local ShotEvent = game.ReplicatedStorage.RE:WaitForChild("Bullet")
local ActivateShot = game.ReplicatedStorage.RE:WaitForChild("ActivateShot")

local function CFramePointRightSide(pos, targetPos)
	local directionToFace = (pos - targetPos ).unit
	local worldUp = Vector3.new(0,1,0)
	local zAxisFace = directionToFace:Cross(worldUp)
	local yAxisFace = directionToFace:Cross(zAxisFace)
	return CFrame.fromMatrix(pos, directionToFace, yAxisFace, -zAxisFace)
end

Event.OnServerEvent:Connect(function(player, mouse)
	if player == game.Players:GetPlayerFromCharacter(Tool.Parent) then
		ActivateShot:FireClient(player)
	end
end)

ShotEvent.OnServerEvent:Connect(function(player, length, unitray,camera, rayVelocity)
	local Character = player.Character
	local origin = Tip.CFrame.p - unitray.Origin
	local direction =	(unitray.Direction - origin).Unit * length
	local newBullet = Instance.new("Part")
	newBullet.Name = ("Bullet")
	local Part = Instance.new("Part", game.Workspace)
	Part.Transparency = 0
	local Raycast_Params = RaycastParams.new()
	Raycast_Params.FilterDescendantsInstances = {Character, Handle, Tip, Part, newBullet, BulletHole}
	Raycast_Params.FilterType = Enum.RaycastFilterType.Blacklist
	local Laser = workspace:Raycast(origin, direction, Raycast_Params)
	
	Part.FormFactor = Enum.FormFactor.Custom
	Part.BrickColor = BrickColor.new("Really red")
	Part.Material = Enum.Material.Neon
	Part.Shape = Enum.PartType.Cylinder
	Part.Anchored = true
	Part.CanCollide = false

	if Laser then
		print(Laser)
		print(Laser.Position)
		print(Laser.Instance)
		print(Laser.Normal)
		print(Laser.Material)
	else
		Laser = {}
		Laser.Position = origin + direction
	end
	
	
	local Distance = (Tip.CFrame.p - Laser.Position).Magnitude
	Part.Size = Vector3.new(Distance,0.25,0.25)
	Part.CFrame = CFramePointRightSide(Tip.CFrame.p, Laser.Position) * CFrame.new(- Distance/2, 0, 0)
	local Humanoid = Tool.Parent:FindFirstChild("Humanoid")
	Humanoid.Health = Humanoid.Health + 40
	
	Debris:AddItem(Part, 0.7)
	
	if Laser then
		local findInstance = Laser.Instance
		if findInstance then
		local HitHumanoid = findInstance.Parent:FindFirstChildWhichIsA("Humanoid")
		
		if not HitHumanoid then
			HitHumanoid = findInstance.Parent.Parent:FindFirstChildWhichIsA("Humanoid")
		end
		
		if HitHumanoid then
			HitHumanoid:TakeDamage(250)
			end
		end
	end
end)	

Any help would be useful since I have no idea what to do.

Would anyone tell me if this new Ray Cast works with ScreenPointToRay and ViewPortToRay?

The ScreenPointToRay function accepts a third argument for the depth of the ray. You could probably set this to 1 for it to be a unit ray.

Is there any way to fix the part from extending from the tip to 0,0,0?

I haven’t used rays that much, someone else may want to intervene.

Nevermind I fixed it but it will not print any part that collides with it and it just goes through every part.

So this is the script that I changed a bit but it would still make the laser and part go through other parts and will not print the ray.


local direction = (unitray.Direction - origin).Unit * length

Here, you don’t have to make a UnitRay from it, because unitray.Direction already is a unitRay. you can just say local direction = unitray.Direction.
And here:

local crosshair_fireX = math.random(CrossFrame.AbsoluteSize.X) 
local crosshair_fireY = math.random(CrossFrame.AbsoluteSize.Y) 

if you want a random value, you have to put in two arguments: the maximum value and minimum value you want to return.

1 Like

Thanks but the math random still works even without two numbers.

Cool, I didn’t know that. Learnt something new today :slight_smile:

I think it works since I add the position with the size of it. But I still have no idea other than what I just said.