Tank game: Issue with Fastcast hit detection, and weld manipulation

So I’m making a multi-crew tank game where you hop on inside the tank and control different crew roles.
I have based the gun/turret rotation based off this concept, where you basically send a remote to the server, telling it where you want to rotate the turret (Weld.C1.Angles property), and sending back the remote to all the clients except the sender, to replicate the changes.

However this led to a big issue. I use fastcast server-side for the tank PvP. And the server does not know where the turret is rotated, (it always thinks its at neutral position facing forward) so it can lead to big problems to where the shell lands. These images explain it:


I have thought of making a WorldModel to put the tanks in and update their CFrames every some heartbeats, and simulate the shell from there. But that would not work because you can’t put terrain in WorldModel. Probably the solution is to simulate the shell on the client instead, but how would the server verify the hits, if it doesn’t know how the target looks like?

-- Client
while task.wait(0.033) do
	if script.Parent then
		if runService:IsRunning() then
			TurretRenderingEvent:FireServer(desiredTurretAngle, desiredGunAngle)
		end
	end
end
-- Server
function RenderTurretForClients(plyr, gunRot, turrRot)
	local GunStats = TankStatsDictionary[plyr.Tank.Name].GunStats

	if GunStats.GunUpperAngle >= gunRot and GunStats.GunLowerAngle <= gunRot then
		local SeatPart = hum.SeatPart

		if SeatPart then
			if SeatPart.Name == "GunnerVehicleSeat" then
				for i, player in ipairs(Players:GetPlayers()) do
					if player ~= plyr then
						TurretRenderingEvent:FireClient(player, turrRot, gunRot, SeatPart)
					end
				end	
			end
		end
	end
end
TurretRenderingEvent.OnServerEvent:Connect(RenderTurretForClients)
-- Other clients
local function RenderTurret(gunRot: number, turrRot: number, seatPart: VehicleSeat)
   -- This does not run for the client rotating the turret
	if turrRot then
		seatPart.TurretRotation.C1 = CFrame.Angles(0, math.rad(turrRot), 0)
	end
	if gunRot then
		seatPart.Elevation.C1 = CFrame.Angles(math.rad(gunRot), 0, 0)
	end
end
TurretRenderingEvent.OnClientEvent:Connect(RenderTurret)

Thanks for any help in advance

Thanks to the insane amount of help I got in the replies (yes sarcasm funny) the answer was more simple than I thought.

-- Client
while task.wait(0,25) do -- All that had to be done is change the interval...
	if script.Parent then
		if runService:IsRunning() then
			TurretRenderingEvent:FireServer(desiredTurretAngle, desiredGunAngle)
		end
	end
end
-- Server
function RenderTurretForClients(plyr, turrRot, gunRot)
	local GunStats = TankStatsDictionary[plyr.Tank.Name].GunStats

	if GunStats.GunUpperAngle >= gunRot and GunStats.GunLowerAngle <= gunRot then
		local SeatPart = hum.SeatPart

		if SeatPart then
			if SeatPart.Name == "GunnerVehicleSeat" then
				for i, player in ipairs(Players:GetPlayers()) do
					if player ~= plyr then
                        --...Remove this...
						--TurretRenderingEvent:FireClient(player, turrRot, gunRot, SeatPart)
					end
				end	
                  --... And add this
                  SeatPart.Elevation.C1 = CFrame.Angles(math.rad(gunRot), 0, 0)
                  SeatPart.TurretRotation.C1 = CFrame.Angles(0, math.rad(turrRot), 0)
			end
		end
	end
end
TurretRenderingEvent.OnServerEvent:Connect(RenderTurretForClients)

The amount of interval (0.25) is this slow because the faster it is, the more the gunner feels like the gun is shaking after he stops rotating it, due to network delays. I think a way to fix it is update the orientation on the gunner client every RenderStep instead of every time he presses a key, but it’s untested.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.