I am trying to make a classic-style board game into a 3d game. My current goal is to make a system where the player can click on a boat (gray part right now) and it will then follow their mouse position over the game board. The tiles that the boat covers highlight green. There are three different sizes: 1 tile boat, 2 tile boat, 3 tile boat. This should be signified by the number of tiles lit up when the boat is hovered over them. Ideally, the boat would latch into exactly where it hypothetically would go if the player were to click when hovering over. Then they could click to place the piece in that spot. But for now im just trying (and failing) to the get basic hover functionality.
I had it half-way working by starting a renderstepping function when the player clicks on the boat, and moving the boats cframe to the players mouse.Hit.Position. This, however, caused it to not trigger the part.Touched property as it uses no physics. So I added a part inside of the boat part which I tried to make follow the boat using linearvelocity so it could trigger the tiles. However, it doesn’t move for some reason and I don’t know why.
Also, using mouse hit cframes created the problem of the mouse hit being on top of the part, and looping this overlap to make the part fly towards the screen. To fix this, I opted (with AI’s advice) to use raycasting and filter out the part from the raycast parameters. This had some annoying consequences, though, as the part no longer follows exactly where the mouse appears to be on screen, and the player can no longer click the part a second time to stop the renderstepping. Also, as seen in the video, it breaks apart terrible when interacting with multiple boats and somehow the part-flying-towards-the-screen issue returns
.
The video shows how it breaks down in real time lol.
I have just begun learning to script and this is driving me crazy. After struggling a while I asked AI for help but it couldnt figure it out either haha. I’m really not sure how to fix it. Thank you for any help!
local plrs = game:GetService("Players")
local player = game:GetService("Players").LocalPlayer
local mouse = game:GetService("MouseService")
local cam = workspace:WaitForChild("Camera")
local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
player.CharacterAdded:Connect(function(char)
if player.Team and player.Team.Name == "Rorshack" then
cam.CameraType = Enum.CameraType.Scriptable
local campart1 = Vector3.new(-382, 42.5, 45.5)
local campart2 = Vector3.new(-382, 6.3, 101)
cam.CFrame = CFrame.lookAt(campart1,campart2)
char.HumanoidRootPart.CFrame = cam.CFrame * CFrame.new(0,-5,0)
char.HumanoidRootPart.Anchored = true
else
cam.CameraType = Enum.CameraType.Scriptable
local campart1 = Vector3.new(-382, 42.5, 154.4)
local campart2 = Vector3.new(-382.8, 6.3, 108.6)
cam.CFrame = CFrame.lookAt(campart1,campart2)
char.HumanoidRootPart.CFrame = cam.CFrame * CFrame.new(0,-5,0)
char.HumanoidRootPart.Anchored = true
end
end)
local slotsFolder = workspace:FindFirstChild("Slots")
if not slotsFolder then
return
end
local boatsFolder = workspace:FindFirstChild("Boats")
if not boatsFolder then
return
end
local ActiveSlots = {}
local moving = false
local linearVelocity = nil
local conn = nil
local function getMouseHit(boat,raycastParams)
local mouse = UserInputService:GetMouseLocation()
local unitRay = cam:ScreenPointToRay(mouse.X, mouse.Y)
local raycastResult = workspace:Raycast(unitRay.Origin, unitRay.Direction * 1000, raycastParams)
if raycastResult then
return raycastResult.Position
end
return nil
end
local function startMoving(boat)
if moving then return end
moving = true
boat.CanCollide = false
boat.CanTouch = false
boat.Anchored = false
local toucher = boat:FindFirstChild("Toucher")
toucher.Anchored = false
if not toucher then
warn("No toucher")
return end
local linearVelocity = toucher.LinearVelocity
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Exclude
raycastParams:AddToFilter(boat)
conn = RunService.RenderStepped:Connect(function()
if not moving then
if conn then conn:Disconnect() end
return
else
local mousepos = getMouseHit(boat,raycastParams)
local targetPos = mousepos
local currentPos = toucher.Position
local direction = (targetPos - currentPos)
linearVelocity.VectorVelocity = direction.Unit * math.min(direction.Magnitude * 100, 100)
boat.CFrame = CFrame.new(mousepos)
task.wait(0.01)
end
end)
end
local function stopMoving(boat)
local toucher = boat.Toucher
moving = false
if linearVelocity then
linearVelocity:Destroy()
linearVelocity = nil
end
if conn then
conn = nil
end
toucher.Anchored = true
boat.CanTouch = true
boat.Anchored = true
end
local function BoatSetup(boat)
if not boat:IsA("BasePart") then
return
end
local clickDetector = boat:FindFirstChildOfClass("ClickDetector")
if not clickDetector then
clickDetector = Instance.new("ClickDetector")
clickDetector.Parent = boat
end
clickDetector.MouseHoverEnter:Connect(function()
boat.Color = Color3.fromRGB(91, 93, 105)
end)
clickDetector.MouseHoverLeave:Connect(function()
boat.Color = Color3.fromRGB(163, 162, 165)
end)
clickDetector.MouseClick:Connect(function()
if not moving then
startMoving(boat)
else
stopMoving(boat)
end
end)
end
local function setupSlot(slot)
if not slot:IsA("BasePart") then
return
end
local clickDetector = slot:FindFirstChildOfClass("ClickDetector")
if not clickDetector then
clickDetector = Instance.new("ClickDetector")
clickDetector.Parent = slot
end
local touchDebounce = false
slot.Touched:Connect(function()
if not touchDebounce then
touchDebounce = true
slot.Color = Color3.fromRGB(0, 170, 0)
table.insert(ActiveSlots,slot)
task.wait(0.1)
touchDebounce = false
else return
end
end)
slot.TouchEnded:Connect(function()
touchDebounce = false
slot.Color = Color3.fromRGB(27, 42, 53)
table.remove(ActiveSlots,slot)
end)
--clickDetector.MouseHoverEnter:Connect(function()
-- slot.Color = Color3.fromRGB(0, 170, 0)
--end)
--clickDetector.MouseHoverLeave:Connect(function()
-- slot.Color = Color3.fromRGB(27, 42, 53)
-- end)
end
-- Setup existing slots
for _, slot in slotsFolder:GetChildren() do
setupSlot(slot)
end
-- Listen for new slots being added
slotsFolder.ChildAdded:Connect(function(child)
setupSlot(child)
end)
for _, boat in boatsFolder:GetChildren() do
BoatSetup(boat)
end
boatsFolder.ChildAdded:Connect(function(child)
BoatSetup(child)
end)