What do you want to achieve? Keep it simple and clear!
I want to achieve server-sided hit detection with a hitbox I’ve already made.
What is the issue? Include screenshots / videos if possible!
For the smoothest-looking physics I’ve done client → server → other clients replication. e.g. Player X has inputted G to spawn the volleyball on their client, then the ball info gets sent into the server, and then the ball is copied over to the other clients to Player X’s position.
My issue with this now, is how do I get all these players to get to collide with this ball through the server, and have the ball still move smoothly across each client via the replication? I’m trying not to use the server to spawn the ball because the Physics become too choppy, and I’m trying to create a similar system in “Volleyball 4.2”, where the ball looks like it moves smoothly across each client, where the hit detection is handled by the server, but balls spawn on each individual client for each player.
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I haven’t tried any solutions since I’ve never done this before and this is too specific to research, but currently the ball spawns on each client and not the server, so do I need to spawn the same ball on the server as well for hit detection? Network ownership I’ve tried before and is unrelated to this topic, as each client is handling the same ball separately on their own clients.
The codes (local script + server script):
--- the local script to spawn the ball on input and send info to server local function createBall(user) local p = vbClone:Clone() local bsClone = ballShadow:Clone() local court = game.Workspace.Template.Flooring.Part local ballTween = TS:Create(p, tweenInfo, Orientation) ballTween:Play() p.Position = user.Character.Head.Position + Vector3.new(0, 15, 0) -- ball spawns 15 studs above players head p.Parent = workspace bsClone.Parent = workspace local shadowcoroutine = coroutine.create(function() --[[this is for that expanding ball-shadow provided in the video]] while RS.Stepped:Wait() do bsClone.Position = Vector3.new(p.Position.X, court.Position.Y + 0.28, p.Position.Z) local bsCloneY = bsClone.Position.Y local vbCloneY = p.Position.Y local mag = vbCloneY - bsCloneY bsClone.Size = Vector3.new(0.2, mag, mag) end end) coroutine.resume(shadowcoroutine) wait(0.2) p.UpPower.Enabled = false --[[this disables since upon spawning the ball, i want it to go upwards for a little while so i add a little force before disabling it]] p.VectorForce.Enabled = true -- this is a force to make the ball feel more floaty end UIS.InputBegan:Connect(function(Input, gameProcessedEvent) local currentPwr = x / maxpwr --[[ ignore these 2, they're used to determine the power of the hit/receive]] local isBounced = false -- spawn ball when pressing G if Input.KeyCode == Enum.KeyCode.G and not gameProcessedEvent and not spawnDebounce then spawnDebounce = true -- debounce remoteEvent:FireServer() -- fire the event to server createBall(player) -- creates the ball for the player using function wait(1) spawnDebounce = false end end)
Moving on to what happens on the server:
local function spawnRemote(player, user) for i,v in ipairs(game.Players:GetPlayers()) do --getting all the players in the game if v ~= player then --[[ all players BUT the one who spawned the ball, (they already ran it on the client in the earlier code at createBall(player) after remoteEvent:FireServer() ]] user = v print(user) remoteEvent:FireClient(v, player) end end end remoteEvent.OnServerEvent:Connect(spawnRemote)
My current server-script that’s below that one that spawns a hitbox that doesn’t work since the ball isn’t spawned on the server:
touchedEvent.OnServerInvoke = function(player, horizontalValue, verticalValue) --local isHit = false if not IsTouched then IsTouched = true local hitbox = game.ReplicatedStorage.hitbox local hitboxclone = hitbox:Clone() local char = player.Character local torso = char:WaitForChild("HumanoidRootPart") local Humanoid = char:WaitForChild("Humanoid") local Weld = Instance.new("WeldConstraint", torso) local Debris = game:GetService("Debris") hitboxclone.CFrame = torso.CFrame - Vector3.new(0, 0, 0.5) Weld.Part0 = torso Weld.Part1 = hitboxclone Weld.Parent = torso local angVel = hitboxclone.AssemblyAngularVelocity hitboxclone.Parent = player.Character hitboxclone:SetNetworkOwner(player) -- sets hitbox network owner to the player Debris:AddItem(hitboxclone, 2) local recAnim = Humanoid:LoadAnimation(rec_Animation) recAnim:Play() local function ball(hit) if hit.Name == "Volleyball" and not isHit and recAnim.IsPlaying and isBounced == false then if isHit == true then return end local hitSound = hit:FindFirstChild("Sounds").rec isHit = true hit.Velocity = hitboxclone.CFrame.LookVector * horizontalValue + hitboxclone.CFrame.UpVector * verticalValue local angVel = hit:FindFirstChild("AngularVelocity") angVel.AngularVelocity = hitboxclone.CFrame.RightVector * -1 * horizontalValue/4 angVel.Enabled = true hitSound:Play() wait(1) isHit = false else return end end hitboxclone.Touched:connect(ball) wait(1) IsTouched = false end end