-
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