Linear Velocity Lagging

I’m creating a combat system and have been trying to add knockback to the last hit of every combo but for some reason it lags when the player attacks a dummy, but not when the dummy attacks a player.

function combatModule.Push(character, root, pushDir, combo, isAttacker)
	if isAttacker and combo == 4 then return end

	local attachment = Instance.new("Attachment", root)
	local linearVelocity = Instance.new("LinearVelocity", root)
	linearVelocity.Attachment0 = attachment
	linearVelocity.MaxForce = 1e7
	linearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
	linearVelocity.VectorVelocity = pushDir * 3
	game.Debris:AddItem(attachment,0.3)
end

This is where the function is being called for reference.

	-- Setup animation and push force
	local gettingHitAnim = script.gettingHitAnims["gettingHit" .. combo]
	local punchVFX = rs.Particles.punchVFX
	local pushForce = (combo == 4) and 10 or 0 -- If combo == 4 push with __ value else do __ value
	local pushDirection = plrRoot.CFrame.LookVector * pushForce
	local hitStun = hitHum:GetAttribute("hitStun")
	local hitIsDummy = hitChar:FindFirstChild("ReviveScript") ~= nil
	local hitPlr = game.Players:GetPlayerFromCharacter(hitChar)
	
	if hitIsDummy then
		-- If a plr hits a dummy, it fires to the server from that players client
		pushRemote:FireServer(hitChar, hitRoot, pushDirection, combo, false, hitIsDummy, hitStun)
		damageRemote:FireServer(hit, 5, gettingHitAnim)
	else if runService:IsClient() then
		--If your hitting a plr as a plr
		pushRemote:FireServer(hitPlr, hitRoot, pushDirection, combo, false, false, hitStun)
		damageRemote:FireServer(hit, 5, gettingHitAnim)
		pushRemote:FireServer(player, plrRoot, pushDirection, combo, true, hitStun)
	else
		-- If a dummy is hitting a plr
		combatModule.Push(hitPlr, hitRoot, pushDirection, combo, false)
		hitHum:TakeDamage(5)
		gettingHitRemote:FireClient(hitPlr, gettingHitAnim, combo)
	end

Fires to the pushRemote are to prevent pushes from happening client side since then they wont replicate to other players clients. Heres the pushRemote script if it matters aswell.

--This script just makes sure that the push runs on the server to prevent client side bugs
local rs = game.ReplicatedStorage
local runService = game["Run Service"]
local pushRemote = rs.serverRemotes.pushRemote
local combatModule = require(rs.CombatModules.hitDetectionModule)

pushRemote.OnServerEvent:Connect(function(player, plr, root, pushDir, combo, attacker, hitStun)
	combatModule.Push(plr, root, pushDir, combo, attacker)
end)

Hitting Dummy:


Getting Hit:

4 Likes

Try using apply impulse on the character’s root to see if the lag is still there

It may depend on the server’s ping.
When the client tells the server to push the dummy, you could make a clone on the client and make the actual dummy invisible, and when the linear velocity is done, you can make it so that the dummy reappears.

1 Like

Also, make sure it’s not exploitable, by adding sanity checks, but other than that good luck!

Set the Network owner to nil on the dummies humanoid root part and that should help. Your client is getting the physics ownership
Here: Network ownership | Documentation - Roblox Creator Hub

2 Likes

To me, this looks like latency between the client and the server. I would do something like what sheeky said and create a whole new dummy on the client, which would mean no latency for you and at worst, a bit of latency for other players.
It would be a little difficult to resync the dummies after the knockback, but you could try moving the parts over time to where the server says they are.

yea this is most definitely the problem. I had to deal with this alot before

1 Like

I tried just setting all humanoids that dont have anchored humRoots and arent players to have nil networkOwnership but it made no difference.

local plrs = game.Players

for i, v in pairs(workspace:getDescendants()) do
	if v:isA("Humanoid") then
		local root = v.Parent.HumanoidRootPart
		if not plrs:GetPlayerFromCharacter(v.Parent) and root.Anchored == false then
			print(v.Parent)
			root:SetNetworkOwner(nil)
		end
	end
end

try setting it to the player instead, not the server

Wouldn’t that cause it to look different on other players clients? I wanna prevent lag on all clients and make sure all players see the same thing if possible.

other players would see the same thing, because the player’s actions will be delayed the same amount of time that the velocity is delayed

I’m fairly certain Strongest Battlegrounds does what I recommended, which is why it look soo satisfying to launch another player across the map, with no latency.
Try what I suggested, it will be worth it.
You could reparent the dummy into replicatedstorage on the client and make a clone of the dummy on the client etc. until the client finishes the LinearVelocity.

Also, before cloning, set Archivable to true because roblox doesn’t let you clone actual players until you set archivable to true, and then once you call the :Clone() set it to false.

The problem with doing that though is my game doesn’t have full stun such as the strongest battlegrounds. ie. during the knockback of an attack the other player may dash away or do something which wouldn’t line up with the clone.

if it matters the bug fixes itself after I kill the dummy once or twice. It changes between 1 or 2 kills each time I run it.

If I wait about a minute before attacking the bug fixes itself, maybe its something to do with not everything being loaded in? It looks similar to this thread, but I’m not sure why it fixes itself after waiting then.

You can possibly follow along the player using interpolation to combat that.

I had a friend test it and he didn’t experience the lag at all. I think it’s something with my studio but I’m not sure what it is. My computer specs are good too so I don’t think that would cause it.

Alright it seems this push function was the solution:

function hitHandler.Push(character, root, pushDir, attacker)
	
	if runService:IsServer() and root:CanSetNetworkOwnership() then
		-- Set ownership to the attacker FIRST
		if attacker and attacker:IsA("Player") then
			root:SetNetworkOwner(attacker)
		end
	end

	local attachment = Instance.new("Attachment")
	attachment.Parent = root
	
	local linearVelocity = Instance.new("LinearVelocity")
	linearVelocity.Attachment0 = attachment
	linearVelocity.MaxForce = 1e7
	linearVelocity.VelocityConstraintMode = Enum.VelocityConstraintMode.Vector
	linearVelocity.VectorVelocity = pushDir * 3
	linearVelocity.Parent = attachment
	
	game.Debris:AddItem(attachment, 0.3)
	
	delay(.5, function()
		if root and root.Parent and root:IsDescendantOf(workspace) then
			root:SetNetworkOwner(nil)
		end
	end)
end

I have no idea how this works so if anyone can explain it would be very helpful.

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