So I’m working on a Golf With Friends remake on roblox but with a twist of making randomly generated obstacles and traps such as bananas that slip you, bombs that blow your ball away and stuff on the course to make it harder to complete, all randomly generated. But first I must begin with creating a golf with friends golf ball system.
I have done this successfully, however it only seems to work inside of Roblox Studio testing. Once I open up the game on the website and play, I can’t seem to move the ball. The way it works is you hold down right mouse button and drag to generate power, but nothing happens at all in the actual roblox game, but studios it’s perfectly fine.
Here are the Client Side for the system, and Server side. And then another server script for spawning the ball in.
Client Side:
local Players = game:GetService(“Players”)
local UserInputSvc = game:GetService(“UserInputService”)
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local RunService = game:GetService(“RunService”)
local player = Players.LocalPlayer
local cam = workspace.CurrentCamera
local ballRef = player:WaitForChild(“Ball”, 20)
if not ballRef or not ballRef.Value then
warn(“Ball not found!”)
return
end
local ball = ballRef.Value
local launchEvent = ReplicatedStorage:WaitForChild(“LaunchBall”)
– GUI references
local playerGui = player:WaitForChild(“PlayerGui”)
local powerGui = playerGui:WaitForChild(“PowerGui”)
local powerBarFill = powerGui:WaitForChild(“PowerBarBackground”):WaitForChild(“PowerBarFill”)
local trailpart = Instance.new(“Part”)
trailpart.Size = Vector3.new(1,1,1)
trailpart.CanCollide = false
trailpart.Transparency = 0.5
trailpart.CFrame = ball.CFrame
trailpart.Parent = ball
local trail = Instance.new(“Trail”)
trail.Attachment0 = Instance.new(“Attachment”, ball)
trail.Attachment1 = Instance.new(“Attachment”, ball)
trail.Attachment0.Position = Vector3.new(0, 0.5, 0) – Adjust offsets
trail.Attachment1.Position = Vector3.new(0, -0.5, 0)
trail.TextureMode = Enum.TextureMode.Wrap
trail.Parent = ball
trail.Enabled = false
local yaw = 0
local pitch = 15
local dist = 15
local sens = 0.2
local minPitch, maxPitch = -80, 80
UserInputSvc.MouseBehavior = Enum.MouseBehavior.LockCenter
UserInputSvc.MouseIconEnabled = false
local dragging = false
local dragStartPos
local MOVEMENT_THRESHOLD = 0.3
local function getMouseHitOnPlane()
local mousePos = UserInputSvc:GetMouseLocation()
local ray = cam:ScreenPointToRay(mousePos.X, mousePos.Y)
local planeY = ball.Position.Y
local origin = ray.Origin
local direction = ray.Direction
if direction.Y == 0 then return nil end
local t = (planeY - origin.Y) / direction.Y
if t < 0 then return nil end
return origin + direction * t
end
local minDragThreshold = 0.01
local maxDragDistance = 10
local minPower = 15
local maxPower = 2000
local min = 0
local max = 1
local TweenService = game:GetService(“TweenService”)
local activeTween
local function updatePowerBar(power)
local clampedPower = math.clamp(power, min, max)
local normalized = (clampedPower - min) / (max - min)
local targetSize = UDim2.new(normalized, 0, 1, 0) -- width of fill
if activeTween then
activeTween:Cancel()
end
activeTween = TweenService:Create(powerBarFill, TweenInfo.new(0.01, Enum.EasingStyle.Quad, Enum.EasingDirection.Out), {
Size = targetSize
})
activeTween:Play()
end
UserInputSvc.InputBegan:Connect(function(input, gameProcessed)
if gameProcessed then return end
if input.UserInputType == Enum.UserInputType.MouseButton2 then
if ball.AssemblyLinearVelocity.Magnitude < MOVEMENT_THRESHOLD then
dragStartPos = getMouseHitOnPlane()
if dragStartPos then
dragging = true
updatePowerBar(minPower)
powerGui.Enabled = true
end
end
end
end)
UserInputSvc.InputChanged:Connect(function(input, gameProcessed)
if gameProcessed then return end
if dragging and input.UserInputType == Enum.UserInputType.MouseMovement then
local dragCurrentPos = getMouseHitOnPlane()
if dragStartPos and dragCurrentPos then
local dirVector = dragStartPos - dragCurrentPos
local dragDistance = dirVector.Magnitude
local power = 0
if dragDistance >= minDragThreshold then
local clampedDistance = math.min(dragDistance, maxDragDistance)
local scale = (clampedDistance - minDragThreshold) / (maxDragDistance - minDragThreshold)
power = minPower + scale * (maxPower - minPower)
end
updatePowerBar(power)
else
updatePowerBar(minPower)
end
end
end)
local strokeCount = 0
– GUI stroke counter setup
local strokeCountGui = game.Players.LocalPlayer:WaitForChild(“PlayerGui”):WaitForChild(“StrokeCountGui”)
local strokeTextLabel = strokeCountGui:WaitForChild(“Frame”):WaitForChild(“TextLabel”)
local TweenService = game:GetService(“TweenService”)
local OOS_UI = game.Players.LocalPlayer:WaitForChild(“PlayerGui”):WaitForChild(“OOS_UI”)
local textLabel = OOS_UI:WaitForChild(“TextLabel”)
textLabel.AnchorPoint = Vector2.new(0.5, 0.5)
textLabel.Position = UDim2.new(0.5, 0, 0.5, 0)
textLabel.Size = UDim2.new(0.01, 0, 0.01, 0)
UserInputSvc.InputEnded:Connect(function(input, gameProcessed)
if gameProcessed then return end
if dragging and input.UserInputType == Enum.UserInputType.MouseButton2 then
dragging = false
powerGui.Enabled = false
local dragEndPos = getMouseHitOnPlane()
if not dragStartPos or not dragEndPos then return end
local dirVector = dragStartPos - dragEndPos
local dragDistance = dirVector.Magnitude
local power = 0
if dragDistance >= minDragThreshold then
local clampedDistance = math.min(dragDistance, maxDragDistance)
local scale = (clampedDistance - minDragThreshold) / (maxDragDistance - minDragThreshold)
power = minPower + scale * (maxPower - minPower)
end
if power > 1 then
local camLook = cam.CFrame.LookVector
local shootDir = Vector3.new(camLook.X, 0, camLook.Z)
if shootDir.Magnitude == 0 then return end
shootDir = shootDir.Unit
launchEvent:FireServer(shootDir, power)
trail.Enabled = true
strokeCount += 1
strokeTextLabel.Text = "" .. strokeCount
print("Stroke count:", strokeCount)
if strokeCount >= 12 then
print("Ran out")
OOS_UI.Enabled = true
textLabel.Size = UDim2.new(0.01, 0, 0.01, 0)
local tweenInfo = TweenInfo.new(5, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
local goal = { Size = UDim2.new(1, 0, 1, 0) }
local tween = TweenService:Create(textLabel, tweenInfo, goal)
tween:Play()
tween.Completed:Connect(function()
OOS_UI.Enabled = false
end)
end
end
end
end)
– CAMERA ORBIT ONLY
RunService.RenderStepped:Connect(function()
if not dragging then
local mx, my = UserInputSvc:GetMouseDelta().X, UserInputSvc:GetMouseDelta().Y
yaw = yaw - mx * sens
pitch = math.clamp(pitch - my * sens, minPitch, maxPitch)
end
local ry, rp = math.rad(yaw), math.rad(pitch)
local offset = Vector3.new(
math.cos(rp)*math.sin(ry),
math.sin(rp),
math.cos(rp)*math.cos(ry)
) * dist
cam.CFrame = CFrame.new(ball.Position + offset, ball.Position)
end)
Server Side:
local ReplicatedStorage = game:GetService(“ReplicatedStorage”)
local RunService = game:GetService(“RunService”)
local launchEvent = ReplicatedStorage:WaitForChild(“LaunchBall”)
local deceleration = 1
print(“SERVER: LaunchBall connected”)
launchEvent.OnServerEvent:Connect(function(player, direction, power)
local ballRef = player:FindFirstChild(“Ball”)
if not ballRef or not ballRef.Value then return end
local ball = ballRef.Value
ball:SetNetworkOwner(nil)
ball.AssemblyLinearVelocity = direction.Unit * power
coroutine.wrap(function()
while true do
local dt = RunService.Heartbeat:Wait()
local vel = ball.AssemblyLinearVelocity
local speed = vel.Magnitude
if speed <= 0.1 then
ball.AssemblyLinearVelocity = Vector3.zero
break
end
local newSpeed = math.max(speed - 1 * dt, 0)
ball.AssemblyLinearVelocity = vel.Unit * newSpeed
end
end)()
end)
Spawning Ball Server Script
local Players = game:GetService(“Players”)
local RunService = game:GetService(“RunService”)
Players.PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
wait(0.1)
if character and character.Parent then
local humanoid = character:FindFirstChildWhichIsA(“Humanoid”)
if humanoid then
humanoid.PlatformStand = true
end
for _, part in ipairs(character:GetDescendants()) do
if part:IsA("BasePart") then
part.CanCollide = false
part.Transparency = 1
end
end
end
local map = workspace:WaitForChild("Maps"):WaitForChild("Map1")
local startPart = map:WaitForChild("Start")
-- Create the ball part
local ball = Instance.new("Part")
ball.Name = player.Name .. "_Ball"
ball.Shape = Enum.PartType.Ball
ball.Size = Vector3.new(1,1,1)
ball.Position = startPart.Position + Vector3.new(0, 3, 0)
ball.Material = Enum.Material.SmoothPlastic
ball.Anchored = false
ball.CanCollide = true
ball.Parent = workspace
ball.CustomPhysicalProperties = PhysicalProperties.new(0.5, 0.3, 0.5)
local decalTexture = "rbxassetid://107553210659998"
local faces = {
Enum.NormalId.Top,
Enum.NormalId.Bottom,
Enum.NormalId.Front,
Enum.NormalId.Back,
Enum.NormalId.Left,
Enum.NormalId.Right,
}
for _, face in ipairs(faces) do
local decal = Instance.new("Decal")
decal.Face = face
decal.Texture = decalTexture
decal.Parent = ball
end
local highlight = Instance.new("Highlight")
highlight.Adornee = ball
highlight.FillTransparency = 1
highlight.OutlineColor = Color3.new(1, 1, 1)
highlight.OutlineTransparency = 0
highlight.Parent = ball
local ballRef = Instance.new("ObjectValue")
ballRef.Name = "Ball"
ballRef.Value = ball
ballRef.Parent = player
end)
end)
remote event and UIs.
Please someone explain how to fix this issue of the studio side working and actual game side not.


