Hello, I am attempting to do a placeables script and so far its gone amazingly. However the placeables can be cast on a table leg or on a wall. I don’t want that i want it so that it can’t be placed onto a wall or table leg and the colour will change red if it can’t be placed there, It can also be placed onto another candle which i don’t want. Does anyone have any idea how to fix this issue?
Local Script:
local Player = game.Players.LocalPlayer
local Character = Player.Character
local RunService = game:GetService("RunService")
local CandleTemplate = script.Parent.Handle
local preview = nil
local UIS = game:GetService("UserInputService")
local castParams = RaycastParams.new()
castParams:AddToFilter(Character)
local function PreparePreviewPart(part)
preview = part:Clone()
preview.Parent = workspace
preview.CanCollide = false
preview.CanQuery = false
preview.Anchored = true
preview.Color = Color3.new(1,1,1)
preview.Transparency = 0.5
preview.Orientation = Vector3.new(0, -90, 0)
end
local function renderPreview()
local mouseloc = UIS:GetMouseLocation()
local unitray = workspace.CurrentCamera:ViewportPointToRay(mouseloc.X, mouseloc.Y)
local cast = workspace:Raycast(unitray.Origin, unitray.Direction * 1000, castParams)
if cast and preview then
preview.Position = cast.Position + cast.Normal * CandleTemplate.Size.Y/2
end
end
task.spawn(function()
UIS.InputBegan:Connect(function(MS)
if MS.UserInputType == Enum.UserInputType.MouseButton1 then
game.ReplicatedStorage.Placeable:FireServer(CandleTemplate, preview.Position, preview.Orientation, script.Parent.Name)
preview:Destroy()
script.Parent:Destroy()
end
end)
end)
script.Parent.Unequipped:Connect(function()
preview:Destroy()
end)
PreparePreviewPart(CandleTemplate)
RunService:BindToRenderStep("Preview", Enum.RenderPriority.Camera.Value, renderPreview)
Server Script:
game.ReplicatedStorage.Placeable.OnServerEvent:Connect(function(Player, Item, Position, Orientation, Name)
local Clone = Item:Clone()
Clone.Parent = workspace
Clone.Position = Position
Clone.Orientation = Orientation
Clone.Anchored = true
Clone.Name = Name
end)
First method:
Shoot ray downwards from mouse location so its always on ground
local function renderPreview()
local mouseloc = UIS:GetMouseLocation()
local unitray = workspace.CurrentCamera:ViewportPointToRay(mouseloc.X, mouseloc.Y)
local mousePos = workspace:Raycast(unitray.Origin, unitray.Direction * 1000, castParams)
local origin = CFrame.new(mousePos.Position) * CFrame.new(0,8,0);
local endPoint = CFrame.new(mousePos.Position) * CFrame.new(0,-64,0);
local direction = endPoint - origin;
local cast = workspace:Raycast(origin, direction, castParams)
if cast and preview then
preview.Position = cast.Position + cast.Normal * CandleTemplate.Size.Y/2
end
end
Second method:
Shoot ray downwards from mouse location and change its color to red if the distance is greater than 0.1 studs
local function renderPreview()
local mouseloc = UIS:GetMouseLocation()
local unitray = workspace.CurrentCamera:ViewportPointToRay(mouseloc.X, mouseloc.Y)
local cast = workspace:Raycast(unitray.Origin, unitray.Direction * 1000, castParams)
local checkGround = workspace:Raycast(cast.Position * Vector3.new(0,0.05,0), (Vector3.new(0,-64,0)*cast) - cast, castParams);
if cast and preview then
if cast - checkGround.Position < 0.1 then
preview.Position = cast.Position + cast.Normal * CandleTemplate.Size.Y/2
else
preview.Color = Color3.fromRGB(255, 0, 0);
end
end
end
These aren’t tested so if there are any errors please let me know.
local function renderPreview()
local mouseloc = UIS:GetMouseLocation()
local unitray = workspace.CurrentCamera:ViewportPointToRay(mouseloc.X, mouseloc.Y)
local mousePos = workspace:Raycast(unitray.Origin, unitray.Direction * 1000, castParams)
if mousePos then
local origin = CFrame.new(mousePos.Position) * CFrame.new(0,8,0);
local endPoint = CFrame.new(mousePos.Position) * CFrame.new(0,-64,0);
local direction = endPoint.Position - origin.Position;
local cast = workspace:Raycast(origin.Position, direction, castParams)
if cast and preview then
preview.Position = cast.Position + cast.Normal * CandleTemplate.Size.Y/2
end
end
end
local function renderPreview()
local mouseloc = UIS:GetMouseLocation()
local unitray = workspace.CurrentCamera:ViewportPointToRay(mouseloc.X, mouseloc.Y)
local mousePos = workspace:Raycast(unitray.Origin, unitray.Direction * 1000)
if mousePos then
local origin = CFrame.new(mousePos.Position) * CFrame.new(0,0.05,0);
local endPoint = CFrame.new(mousePos.Position) * CFrame.new(0,-32,0);
local direction = endPoint.Position - origin.Position;
local checkGround = workspace:Raycast(origin.Position, direction);
local distance:number = mousePos.Position.Y - checkGround.Position.Y;
if distance < 0.1 then
previewPart.Position = mousePos.Position + mousePos.Normal;
previewPart.Color = Color3.fromRGB(255, 255, 255);
else
previewPart.Color = Color3.fromRGB(255, 0, 0);
end
end
end
If possible create a boolean variable when the object is red so the user cant place it
I think this maybe more difficult because I’m assuming the wall you have are not flat like mine so that means you would need to add the list of parts/objects to the exclude in the raycast parameters. Try to get all the parts that you dont want it to place it on and add it to the raycast parameters.