part.Touched Does not work as intended [repost] 2

im creating a collision sytem yor my game but it doesn’t work,
here’s the script:

localScript:

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 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.Parent = workspace
		for i, object in ipairs(Model:GetDescendants()) do
			if object:IsA("BasePart") then
				PhysicsService:SetPartCollisionGroup(object, "FurnitureTemplate")
				object.Material = Enum.Material.ForceField
			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
			
			Model.PrimaryPart.Touched:Connect(function(hit)
				--some function im gonna add
			end)
			
			local cframe = CFrame.new(x,y,z)
			Model:SetPrimaryPartCFrame(cframe)
		end
	end
end)

hope this hepls to help me

oh i forgot, the part.touched works if it touches the player character

3 Likes

Do you mind explaining how it doesn’t work? Or what it’s meant to do in the first place?

3 Likes

im creating collision for the furniture in my game so it doesn’t clip in the walls

but the collision only works if the furniture primarypart touches the character

3 Likes

Why would you need a script to control this since roblox already has the “CanCollide”.

1 Like

the CanCollide is for get collision on a object and cantouch if is true you can do part.touched

2 Likes

wait ill’ do a video for you to see

2 Likes

here’s the video
robloxapp-20231228-1711125.wmv (669.5 KB)

1 Like

I don’t exactly get how the script or game is supposed to work. Do you mind explaining what the script is meant to prevent and how the game works?

2 Likes

ok the script finds the position of the mouse using raycast then the object get positioned by the raycast x y z

2 Likes

Probably because the .Touched event isn’t connected to an actual function.

1 Like

what are you meaning that it isn’t connected to an actual function

1 Like

part.Touched isn’t working as intended because you haven’t made it do anything yet. Look at your code.

1 Like

uhh i tried


but it works with the character parts

1 Like

You’re probably clicking one of the character parts on accident. Add the player’s character to your raycastParams.FilterDescendantsInstances array.

1 Like

no it’s not that i mean it doesn’t detect walls ceiling touching the base part

1 Like

This should not be in the RunService loop. It will call itself after being defined one time.

Model.PrimaryPart.Touched:Connect(function(hit)
	--some function im gonna add
end)
-- then add the ...
RunService.RenderStepped:Connect(function()
1 Like

wait, no it can’t because at the start of the game the model will be Nil
but then the value changes

1 Like

Add a check inside the part.Touched connection.

Model.PrimaryPart.Touched:Connect(function(hit)
    if Model then
        -- Rest of code here
    end
end)

Edit: Oh wait, I see what you mean, just reconnect the function whenever you change the Model variable. Only you can change it, and when you do, reconnect the function. Like this:

local function primaryPartTouched(hit)
    -- Code
end

-- Somewhere else in the code
Model = -- Blah blah blah
Model.PrimaryPart.Touched:Connect(primaryPartTouched)

@matolol2011

1 Like

At the top of the code add … local Model = nil
Presetting a variable to be used later.
(you’re faking it untill it’s defined)

1 Like

it doesn’t work ._.

1 Like