So I’m making a throwable rock, and I have one created on the client immediately when they click. I then invoke the server to tell the server to create the same rock. I then return the server rock to the client via invoking the client, so the client can destroy the server rock and doesn’t see a second rock on their screen. This process is used so the client throwing the rock can see it be thrown smoothly.
For full disclosure of the code in hopes of finding a solution, the code I used to model the parts’ motion was taken from this post written by EgoMoose.
ServerRockHandler
local throwRock = script.Parent:WaitForChild("ThrowRock")
local travelTime = 0.5
throwRock.OnServerInvoke = function(player, mousePosition)
local rock = player.Character:FindFirstChild("Rock")
if rock and rock:IsA("Tool") then
local humanoidRootPart = player.Character.HumanoidRootPart
local gravity = Vector3.new(0, -workspace.Gravity, 0)
local x0 = humanoidRootPart.CFrame * Vector3.new(0, 2, -2)
local v0 = (mousePosition - x0 - 0.5 * gravity * travelTime * travelTime) / travelTime
local actualRock = rock:FindFirstChild("Handle"):Clone()
actualRock.Velocity = v0
actualRock.CFrame = CFrame.new(x0)
actualRock.CanCollide = true
actualRock.Parent = workspace
local deleteRock = throwRock:InvokeClient(player, actualRock)
rock:Destroy()
end
return
end
ClientRockHandler
local UserInputService = game:GetService("UserInputService")
local rock = script.Parent
local throwRock = script.Parent:WaitForChild("ThrowRock")
local player = game:GetService("Players").LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local equipped = false
rock.Equipped:Connect(function()
equipped = true
end)
rock.Unequipped:Connect(function()
equipped = false
end)
UserInputService.InputBegan:Connect(function(input, gPE)
if input.UserInputType == Enum.UserInputType.MouseButton1 and not gPE then
if equipped then
local mousePos = input.Position
local mouseRay = workspace.CurrentCamera:ScreenPointToRay(mousePos.X, mousePos.Y)
local spaceRay = Ray.new(mouseRay.Origin, mouseRay.Direction * 1000)
local target, position = workspace:FindPartOnRay(spaceRay, character)
local humanoidRootPart = player.Character.HumanoidRootPart
local gravity = Vector3.new(0, -workspace.Gravity, 0)
local x0 = humanoidRootPart.CFrame * Vector3.new(0, 2, -2)
local travelTime = 0.5
local v0 = (position - x0 - 0.5 * gravity * travelTime * travelTime) / travelTime
local actualRock = rock:FindFirstChild("Handle"):Clone()
actualRock.Velocity = v0
actualRock.CFrame = CFrame.new(x0)
actualRock.CanCollide = true
actualRock.Parent = workspace
throwRock:InvokeServer(position)
end
end
end)
throwRock.OnClientInvoke = function(serverRock)
if serverRock then
serverRock:Destroy()
end
return
end
My specific issue seems to come from the following code segment
throwRock.OnClientInvoke = function(serverRock)
if serverRock then
serverRock:Destroy()
end
return
end
or more specifically, this line
serverRock:Destroy()
When this line is commented out, I get the following result,
As you can see, both the client and server rock are visible from the client as expected since the server rock was not deleted on the client. From the servers view, the server rock properly reached its destination.
But not if we do not comment that line out, the following happens,
As shown, the client properly sees only one rock, as the server rock was deleted. The issue is that the server rock seems to just freeze in place.
I’m pretty lost on what’s going on here, so any insight into this issue is welcome!