Part moving on the client does not work with .Touched Events

Hello! I’m having trouble finding a way to make a “range” system in my incremental game. Basically, I have a RangePart which is moved via localscript so that it does not replicate to other clients and cause weird stuff to happen. The RangePart should be able to be detected by .Touched events in other parts, but since .Touched events only work on the server, it cannot be detected. How can I fix this?

Code:

--CornHandler LocalScript
print("Running")
local RepStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local plr = Players.LocalPlayer

local Values = RepStorage:WaitForChild("Values")
local cornamount = Values:WaitForChild("CornAmount")
local Time = Values:WaitForChild("Time")
local Cap = Values:WaitForChild("Cap")
local Val = Values:WaitForChild("Val")

local dirt = game.Workspace:WaitForChild("dirt")
local corn = RepStorage:WaitForChild("corn")
local RangePart = game.Workspace:WaitForChild("RangePart")

local CornHarvestEvent = RepStorage:WaitForChild("CornHarvestEvent")

local overlap = OverlapParams.new()
overlap.FilterType = Enum.RaycastFilterType.Include
overlap.FilterDescendantsInstances = {game.Workspace:WaitForChild("Corns")}

local function addcorn()
	task.wait(Time.Value)
	local corn2 = corn:Clone()
	corn2.Parent = game.Workspace:WaitForChild("Corns") 

	corn2.Position = Vector3.new(dirt.Position.X + (math.random(-dirt.Size.X / 2, dirt.Size.X / 2)),dirt.Position.Y + dirt.Size.Y,dirt.Position.Z + (math.random(-dirt.Size.Z / 2, dirt.Size.Z / 2)))
	local dupeCheck = workspace:GetPartsInPart(corn2,overlap)
	if dupeCheck[1] then
		corn2:Destroy()
		wait(.1)
		addcorn()
		return
	end
	cornamount.Value += 1
	
	corn2.Touched:Connect(function(hit)
		print(hit)
		if hit.Name == "RangePart" then
			corn2:Destroy()
			cornamount.Value -= 1
			CornHarvestEvent:FireServer(Val.Value)
		end
	end)
end

while wait() do
	if cornamount.Value < Cap.Value then
		addcorn()
	end
end
--RangeFollow, LocalScript
local RunService = game:GetService("RunService")
local RepStorage = game:GetService("ReplicatedStorage")

local Vals = RepStorage:WaitForChild("Values")
local Range = Vals:WaitForChild("Range")

local RangePart = game.Workspace:WaitForChild("RangePart")
local dirt = game.Workspace:WaitForChild("dirt")
local char:Model = script.Parent

local Overlap = OverlapParams.new()
Overlap.FilterType = Enum.RaycastFilterType.Include
Overlap.FilterDescendantsInstances = {char}

local tween = game:GetService("TweenService"):Create(RangePart,TweenInfo.new(0.5,Enum.EasingStyle.Exponential,Enum.EasingDirection.Out),{
	Size = Vector3.new(RangePart.Size.X,Range.Value,Range.Value)
}
)
local tweenEnd = game:GetService("TweenService"):Create(RangePart,TweenInfo.new(0.5,Enum.EasingStyle.Exponential,Enum.EasingDirection.Out),{
	Size = Vector3.new(RangePart.Size.X,0.1,Range.Value)
}
)

RunService.Heartbeat:Connect(function()
	RangePart.Position = Vector3.new(char.PrimaryPart.Position.X,char.PrimaryPart.Position.Y - 4.5,char.PrimaryPart.Position.Z)
	
	local plrCheck = workspace:GetPartBoundsInBox(CFrame.new(dirt.Position),Vector3.new(dirt.Size.X,100,dirt.Size.Z),Overlap)
	if plrCheck[1] then
		tween:Play()
	elseif not plrCheck[1] then
		tweenEnd:Play()
	end
end)

.Touched events should work on both the Client and the Server as far as I’m aware.

No, the event listener only checks if the part is touched on the server, not the client. The only reason it would work on a localscript is if the part was moved on the server, which would then be replicated to the client

I got the solution
Found through testing that I could use spatial queries, specifically workspace:GetPartsInPart() to make it work
Code:

--RangeFollow, LocalScript
local RunService = game:GetService("RunService")
local RepStorage = game:GetService("ReplicatedStorage")

local CornHarvestEvent = RepStorage:WaitForChild("CornHarvestEvent")

local Vals = RepStorage:WaitForChild("Values")
local Range = Vals:WaitForChild("Range")
local cornamount = Vals:WaitForChild("CornAmount")
local Val = Vals:WaitForChild("Val")

local RangePart = game.Workspace:WaitForChild("RangePart")
local dirt = game.Workspace:WaitForChild("dirt")
local char:Model = script.Parent

local Overlap = OverlapParams.new()
Overlap.FilterType = Enum.RaycastFilterType.Include
Overlap.FilterDescendantsInstances = {char}

local Overlap2 = OverlapParams.new()
Overlap2.FilterType = Enum.RaycastFilterType.Include
Overlap2.FilterDescendantsInstances = {game.Workspace:WaitForChild("Corns")}

local tween = game:GetService("TweenService"):Create(RangePart,TweenInfo.new(0.5,Enum.EasingStyle.Exponential,Enum.EasingDirection.Out),{
	Size = Vector3.new(RangePart.Size.X,Range.Value,Range.Value)
}
)
local tweenEnd = game:GetService("TweenService"):Create(RangePart,TweenInfo.new(0.5,Enum.EasingStyle.Exponential,Enum.EasingDirection.Out),{
	Size = Vector3.new(RangePart.Size.X,0.1,Range.Value)
}
)

RunService.Heartbeat:Connect(function()
	
	RangePart.Position = Vector3.new(char.PrimaryPart.Position.X,char.PrimaryPart.Position.Y - 4.5,char.PrimaryPart.Position.Z)
	
	local plrCheck = workspace:GetPartBoundsInBox(CFrame.new(dirt.Position),Vector3.new(dirt.Size.X,100,dirt.Size.Z),Overlap)
	if plrCheck[1] then
		tween:Play()
	elseif not plrCheck[1] then
		tweenEnd:Play()
	end
	
	local harvestCheck = workspace:GetPartsInPart(RangePart,Overlap2)
	if harvestCheck[1] then
		harvestCheck[1]:Destroy()
		cornamount.Value -= 1
		CornHarvestEvent:FireServer(Val.Value)
	end
end)

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