Hey DevForum! I’m making a tower defense game for fun, and when making the placement of the towers it is looking really un-smooth. (I’m having a brain fart for the word)
I think that if there is some way to make the raycast completely ignore the tower and just continue raycasting to the baseplate it would make it 100x more smooth. Right now the raycast just doesn’t do anything if the mouse is over the tower. Here is my code:
local runService = game:GetService("RunService")
local repStorage = game:GetService("ReplicatedStorage")
local players = game:GetService("Players")
local player = players.LocalPlayer
local mouse = player:GetMouse()
local ground = workspace:WaitForChild("Baseplate")
local towerModel = nil
game:GetService("UserInputService").InputBegan:Connect(function(input)
if input.KeyCode == Enum.KeyCode.E then
towerModel = repStorage.Towers["Soldier"]:Clone()
towerModel.Parent = workspace
towerModel:PivotTo(CFrame.new(mouse.Hit.Position.X, 1.5, mouse.Hit.Position.Z))
end
end)
mouse.Move:Connect(function()
if towerModel then
local target = mouse.Hit.Position
local unit = workspace.CurrentCamera:ScreenPointToRay(mouse.X, mouse.Y, 1)
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {towerModel}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
local raycastResults = workspace:Raycast(unit.Origin, unit.Direction*10000, raycastParams)
if raycastResults and raycastResults.Instance == ground then
towerModel:PivotTo(CFrame.new(target.X, 0, target.Z))
end
end
end)
mouse.Button1Down:Connect(function()
if towerModel then
towerModel.Parent = workspace.PlacedTowers
towerModel = nil
end
end)
If you want just the baseplate to be taken into account, you could set your RaycastParams FilterType to Include and then just set the FilterDescendantsInstances to the baseplate.
But if you want just the tower to be excluded, you need to pass your raycastParams to your workspace:Raycast call, it’s missing here:
local raycastResults = workspace:Raycast(unit.Origin, unit.Direction*10000)
^this line should be
local raycastResults = workspace:Raycast(unit.Origin, unit.Direction*10000, raycastParams)
Think it’s because you’re using the mouse.Hit, the mouse raycast is isolated from any other raycasts. The RaycastResult will have a Position property, try using that instead of mouse.Hit.
It’s probably advisable in all cases to be using UserInputService anyway in place of the mouse.
So your final mouse.Move connection would look something like:
mouse.Move:Connect(function()
if towerModel then
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams.FilterDescendantsInstances = {towerModel}
local mouse = userInputService:GetMouseLocation()
local unit = workspace.CurrentCamera:ViewportPointToRay(mouse.X, mouse.Y, 1)
local raycastResults = workspace:Raycast(unit.Origin, unit.Direction*1000, raycastParams)
if raycastResults and raycastResults.Instance == ground then
local target = raycastResults.Position
towerModel:PivotTo(CFrame.new(target.X, 0, target.Z))
end
end
end)