Part.Touched Not Working As Intended

last time i created the same thing but no one responded but i’ve fixed something, but it doesn’t work as intended! part.touched is working if is touching the player’s characrer here’s what i’ve done so far:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")
local PhysicsService = game:GetService("PhysicsService")
local UserInputService = game:GetService("UserInputService")

local Objects = ReplicatedStorage:WaitForChild("Furniture")
local Events = ReplicatedStorage:WaitForChild("Events")
local SpawnFurnitureEvent= Events:WaitForChild("SpawnFurniture")

local Camera = workspace.CurrentCamera

local Gui = script.Parent
local Inventory = Gui.Inventory
local Categories = Gui.Categories
local Template = Inventory.Template
local Model = nil

local IsPlacing = false

local function primaryPartTouched(hit)
	print("cannot touch", hit.Name)
end

local function MouseRaycast(blacklist)
	local MousePosition = UserInputService:GetMouseLocation()
	local MouseRay = Camera:ViewportPointToRay(MousePosition.X, MousePosition.Y)
	local raycastParams = RaycastParams.new()
	raycastParams.FilterType = Enum.RaycastFilterType.Exclude
	raycastParams.FilterDescendantsInstances = blacklist

	local RaycastResult = workspace:Raycast(MouseRay.Origin, MouseRay.Direction * 1000, raycastParams)
	return RaycastResult
end

function CreateTemplate(ModelName)
	local model = Objects:FindFirstChild(ModelName, true)
	if model then
		Model = model:Clone()
			Model.PrimaryPart.Touched:Connect(primaryPartTouched)
		Model.Parent = workspace
		for i, object in ipairs(Model:GetDescendants()) do
			if object:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(object, "FurnitureTemplate")
				object.Material = Enum.Material.ForceField
				object.Color = Color3.new(0.3, 1, 0)
			end
		end
	end
end

function Create3D(ViewportFrame, ViewportImage)
	local Distance = ViewportImage.PrimaryPart.Size.X + ViewportImage.PrimaryPart.Size.Z - ViewportImage.PrimaryPart.Size.Y
	if ViewportImage.PrimaryPart.Size.X < ViewportImage.PrimaryPart.Size.Y and ViewportImage.PrimaryPart.Size.Z < ViewportImage.PrimaryPart.Size.Y then
		Distance = ViewportImage.PrimaryPart.Size.Y
	end
	local cframe = CFrame.new(0,0,Distance * -1)
	ViewportImage:PivotTo(cframe)
	local Camera = Instance.new("Camera", ViewportFrame)
	ViewportFrame.CurrentCamera = Camera
	ViewportFrame.CurrentCamera.CFrame = CFrame.new(0,0,0)
	while RunService.Stepped:Wait() do
		cframe = ViewportImage.PrimaryPart.CFrame * CFrame.Angles(0,math.rad(2),0)
		ViewportImage:PivotTo(cframe)
	end
end

for i, object in pairs(Objects:GetDescendants()) do
	if object:IsA("Model") then
		local Tab = Template:Clone()
		Tab.FurnitureName.Text = object.Name
		Tab.Name = object.Name
		local ViewportImage = object:Clone()
		ViewportImage.Parent = Tab.ViewportFrame
		coroutine.wrap(Create3D)(Tab.ViewportFrame, ViewportImage)
		Tab.Visible = true
		Tab.Parent = Inventory
		Tab.MouseButton1Click:Connect(function()
			if IsPlacing == false then
				IsPlacing = true
				CreateTemplate(object.Name)
			end
		end)
	end
end

function ChangeCategory(categoryName)
	for i, object in pairs(Objects:GetDescendants()) do
		if object:IsA("Model") then
			if categoryName == "All" then
				Gui.Inventory[object.Name].Visible = true
			else
				if object.Parent.Name == categoryName then
					Gui.Inventory[object.Name].Visible = true
				else
					Gui.Inventory[object.Name].Visible = false
				end
			end
		end
	end
end

for i, category in pairs(Categories:GetChildren()) do
	if category:IsA("GuiButton") then
		category.MouseButton1Click:Connect(function()
			ChangeCategory(category.Name)
		end)
	end
end

UserInputService.InputBegan:Connect(function(input, processed)
	if processed then return end
	
	if Model then
		if input.UserInputType == Enum.UserInputType.MouseButton1 then
			SpawnFurnitureEvent:FireServer(Model.Name, Model.PrimaryPart.CFrame)
			Model:Destroy()
			Model = nil
			IsPlacing = false
		end
	end
end)

RunService.RenderStepped:Connect(function()
	if Model then
		local result = MouseRaycast({Model})
		if result and result.Instance then
			local x = result.Position.X
			local y = result.Position.Y + (Model.PrimaryPart.Size.Y / 2)
			local z = result.Position.Z
			
			local cframe = CFrame.new(x,y,z)
			Model:SetPrimaryPartCFrame(cframe)
		end
	end
end)

please help im trying by 5 days to fix this issue

3 Likes

You need to elaborate in your post, what is the actual issue?

1 Like

sorry i was offline, the problem is it doesn’t touch the parts but onnly the character

1 Like

I don’t think touch events work in local scripts so you may have to fire to the client through a server script.

1 Like

but the model needs to be created in the local because other players can see the template for placing

Try using a remote event to alternate in between local and server.

2 Likes

so you mean i create a template in the server and then destroy it?

1 Like

Yeah you should try that. Also, I was wrong, touch events do work in local scripts, as long as it is not in workspace.

1 Like

i even tried getting a model in workspace using a local script but it didn’t work, but now im trying to go from local to server to module

1 Like

Did it work?

hdgsedgstgegdaddwadawedadwadwa

1 Like

im creating the module script it’s a little hard to create a furniture placing game

@Kilpamations And I Think It Doesn’t Work

They do, .Touched is just really unreliable.

1 Like

You can have “Local” Scripts run anywhere, just have a script set on client context.

but now i need help, i tried getting the collision on the server but it doesn’t work!

sometimes corountine.wrap blocks entire code, i had this issue with my module script few months ago, you have to make

local thread = corountine.create(function() -- code to start function here end)
corountine.resume(thread)(variables)

sometimes it work sometimes not, it depends, maybe it’s error inside function that makes corountine breaks, you have to experiment with this

3 Likes

it gave me error idk how to do it

local Collide = coroutine.create(function(ModelName, ModelCFrame)
	while RunService.Stepped:Wait() do
		if IsPlacing == false then
			print("Im Not Placing Anymore")
			break
		else
			print("Im Checking")
			IsColliding = CheckCollisionEvent:FireServer(ModelName, ModelCFrame)
			if IsColliding == true then
				for i, object in ipairs(Model:GetDescendants()) do
					if object:IsA("BasePart") then
						object.Material = Enum.Material.ForceField
						object.Color = Color3.new(1, 0, 0)
					end
				end
			else
				for i, object in ipairs(Model:GetDescendants()) do
					if object:IsA("BasePart") then
						object.Material = Enum.Material.ForceField
						object.Color = Color3.new(0, 1, 0)
					end
				end
			end
		end
	end
end)

function CreateTemplate(ModelName)
	local model = Objects:FindFirstChild(ModelName, true)
	if model then
		Model = model:Clone()
			coroutine.resume(Collide)(Model.Name, Model.PrimaryPart.CFrame) -- it gave me error here
		Model.Parent = workspace
		for i, object in ipairs(Model:GetDescendants()) do
			if object:IsA("BasePart") then
				object.CollisionGroup = "FurnitureTemplate"
				object.Material = Enum.Material.ForceField
				object.Color = Color3.new(0.3, 1, 0)
			end
		end
	end
end
3 Likes

maybe try to put corountine before resume, it will not be redable but… maybe work

Are you trying to make it so if the player touches the furniture? If yes then do

local function primaryPartTouched(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if player then
		print("cannot touch")
	end
end

else just do if player then return end

What’s the progress on fixing it?