Raycast different between server and client

I have these 2 scripts on the client and the server, both using the same Validator module to validate stuff. This validator creates a raycast, and in theory, it should be the same between the server and the client. But it’s different, the raycast on the server does not hit anything. If anyone has a solution, I’d be very grateful.

This is the print log.
image

-- server
local object
	
	if special then
		object = RS.Accessories:FindFirstChild(name)
	else
		object = RS.Placables:FindFirstChild(name,true)
	end
	
	local plot = OccupiedPlots[player.UserId]
	if not object or not plot then return false end
	
	local result 
	local raycast: RaycastResult
	
	local newObj = object:Clone()
	newObj:PivotTo(targetCf)
	
	if not special then
		result = Validator.IsWithinBounds(plot, object.Box:GetExtentsSize(), targetCf) and Validator.NotCollidingObjects(plot, object.Box:GetExtentsSize(), targetCf)
	else
		result, raycast = Validator.ItemValidation(plot, newObj)
		print("server: "..tostring(result))
		print("server: "..tostring(newObj:GetPivot()))
	end
	
	if result and not special then
		newObj.Parent = plot.StoreItems
		return true
	elseif result and special then
		newObj.Parent = raycast.Instance
		raycast.Instance:SetAttribute("Occupied", true)
		return true
	else
		newObj:Destroy()
		return false
	end
--local
local cast = CastMouse(self.Preview)
if cast and cast.Instance and self.Special and cast.Instance.Parent.Name == "PlacableAreas" then
		local position = cast.Instance.Position
		local CF = CFrame.new(position) * CFrame.Angles(0,self.Rotation,0)
		self.Preview:PivotTo(CF)

		self.Preview:FindFirstChild("SelectionBox",true).Adornee = self.Preview
		
		local result, raycast = Validator.ItemValidation(self.Plot, self.Preview)
		print("local: "..tostring(result))
		print("local: "..tostring(self.Preview:GetPivot()))
	
		self.Preview:FindFirstChild("SelectionBox",true).Color3 = 
			if Validator.ItemValidation(self.Plot, self.Preview) then 
				Color3.new(0.184314, 1, 0)
			else 
				Color3.new(1, 0, 0)
	end	
--validator
function module.ItemValidation(plot: Model, object: BasePart)
	local params = RaycastParams.new()
	params.FilterType = Enum.RaycastFilterType.Include
	local filteredItems = {}
	
	for _,v:BasePart in plot.StoreItems:GetDescendants() do
		if not v:FindFirstChildOfClass("SelectionBox", true) then continue end
		table.insert(filteredItems, v)
	end
	
	for _,v in filteredItems do
		params:AddToFilter(v)
	end
	
	local originPoint: Vector3 = object.Position + Vector3.new(0,0.5,0)
	local destination: Vector3 = object.Position + Vector3.new(0,-1.4,0)
	
	if RunS:IsServer() then
		print("module server: "..tostring(object:GetPivot()))
	else
		print("module local: "..tostring(object:GetPivot()))
	end
	local raycast = workspace:Raycast(originPoint, destination - originPoint, params)
	
	if raycast and raycast.Instance and table.find(filteredItems, raycast.Instance) and not raycast.Instance:GetAttribute("Occupied") then
		return true, raycast
	end
	
	return false
	
end

Is the object moving at the time of the raycast?
Does the object exist on both the server and client?

The CFrame printed is the same across 3 scripts, so I don’t think that it’s moving. The client has a preview model to move and rotate around, and when they click, it invokes a remote function to clone it on the server side.

It turns out that I totally forgot about replication in the code, so the if condition failed on the server, because I only created those parts on the client. I changed the if condition to something else, and now it works well.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.