Why is Ray Cast not working as expected?

  1. What do you want to achieve? I want to make a gun using ray casting

  2. What is the issue? There’s an error and it’s saying “Workspace.PistolReward.Main:25: attempt to index nil with 'UnitRay”

  3. What solutions have you tried so far? Dev hub, YouTube, dev fourm.

--//Players

local Character 
local PlayerMouse
--//Replicated Storage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RepGame = ReplicatedStorage.Game
local GunItems  = RepGame.Gun
local Bullet = GunItems.Bullet

--//Remotes
local EventFire = script.Parent.Fire

--//Extra
local GunshotSound = game.Workspace.Audio.gunshot
local Barrel = script.Parent.Barrel

function GunFired()
	EventFire.OnServerEvent:Connect(function(Mouse,Play)
		Character = Play
		PlayerMouse = Mouse
		
		local RayStart = Barrel.Position
		local Mouse = PlayerMouse:GetMouse()
		local mouseRay = Mouse.UnitRay --Error
		local castRay = Ray.new(mouseRay.Origin, mouseRay.Direction * 1000)
		local RayParams = RaycastParams.new()
		
		RayParams.FilterDescendantsInstances = {Barrel.Parent}
		RayParams.FilterType = Enum.RaycastFilterType.Blacklist
		
		local Result = game.Workspace:Raycast(RayStart, castRay, RayParams)
		
		
		if Result then
			local Hit = Result.Instance
			
			if Hit.Parent.Parent == game.Workspace then
				print("Workspace")
			end
			
		end

	
	end)
end

GunFired()
4 Likes

You can’t get the player mouse on the server, it has to be a LocalScript in order to work.

1 Like

I passed the players mouse from the Client through the fire server

1 Like

FireServer always starts with the argument “Player”, so the order would have to be Player,Mouse.

1 Like

I did here is the script so you can see

local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character
local PlayerMouse = Player:GetMouse()

--//Replicated Storage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RepGame = ReplicatedStorage.Game
local GunItems  = RepGame.Gun
local Bullet = GunItems.Bullet

--//Remotes
local EventFire = script.Parent.Fire

--//Extra
local GunshotSound = game.Workspace.Audio.gunshot
local Barrel = script.Parent.Barrel

function FireGun()
	script.Parent.Activated:Connect(function()
		EventFire:FireServer(PlayerMouse,Character)
		print("Gun Fired")
	end)
end

FireGun()

1 Like

@BuilderDolphin is right. You may have misunderstood. When you :FireServer(PlayerMouse, Character), the OnServerEvent parameter will automatically get a new parameter, which is the player who fired the event.

So the .OnServerEvent will get Player, PlayerMouse, Character.

If you do print(mouse), I predict you would get the player name, not the mouse.

You may also have another issue, which is that it may not be possible to send a mouse instance through a remote event. Maybe consider sending the UnitRay instead through the remote event.

1 Like

Small nitpick, but

You could just connect your GunFired function to the OnServerEvent, that’s what Events are used for connecting to

You have to reference one of the properties of the Mouse to pass onto the server, you can’t just get it from a Script hence why it results as an error because the Mouse is only visible to the client only

-- SERVER --

--//Players

local Character 
local PlayerMouse
--//Replicated Storage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RepGame = ReplicatedStorage.Game
local GunItems  = RepGame.Gun
local Bullet = GunItems.Bullet

--//Remotes
local EventFire = script.Parent.Fire

--//Extra
local GunshotSound = game.Workspace.Audio.gunshot
local Barrel = script.Parent.Barrel

local function GunFired(Player, MousePos)
	Character = Player
	PlayerMouse = MousePos

    local Origin = Barrel.Position
    local EndPosition = MousePos 

	local RayParams = RaycastParams.new()
		
	RayParams.FilterDescendantsInstances = {Barrel.Parent}
	RayParams.FilterType = Enum.RaycastFilterType.Blacklist
		
	local Result = workspace:Raycast(Origin, (EndPosition).Unit * 1000, RayParams)
	if Result then
		local Hit = Result.Instance
			
		if Hit.Parent.Parent == game.Workspace then
			print("Workspace")
		end

	end
end

EventFire.OnServerEvent:Connect(GunFire)
-- LOCAL --

local Players = game:GetService("Players")
local Player = Players.LocalPlayer
local Character = Player.Character
local PlayerMouse = Player:GetMouse()

--//Replicated Storage
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RepGame = ReplicatedStorage.Game
local GunItems  = RepGame.Gun
local Bullet = GunItems.Bullet

--//Remotes
local EventFire = script.Parent.Fire

--//Extra
local GunshotSound = game.Workspace.Audio.gunshot
local Barrel = script.Parent.Barrel

local function FireGun()
	EventFire:FireServer(PlayerMouse.Hit.Position)
	print("Gun Fired")
end

script.Parent.Activated:Connect(FireGun)
2 Likes

Well, the main error with this server script is that you cannot send object values with RemoteEvents. Edit: Above an issue is also stated

So would I do all this in the local script than fire it to the server script?

2 Likes

Well here’s my suggestion to change the script: Send the server the mouse.Hit position when firing. Then raycast from the server’s end to determine the hit position.

1 Like