I would probably record a tick
for when the victim’s CFrame was recorded using GetPropertyChangedSignal
or Heartbeat
, and whenever the shot was fired, record the signal’s tick
and wait for the next update from the victim’s position, and lerp between the last CFrame and the current one, using the shot’s tick as basis for the alpha.
Pseudocode:
-- function to be connected to an event
-- both are players
function OnShotFired(shooter,victim)
local shotTick = tick()
--not a property, would be recorded somehow
local lastVTick = victim.LastTick
local lastVCFrame = victim.LastCFrame
local hrp = -- victim's HRP
hrp:GetPropertyChangedSignal("CFrame"):Wait()
local newVTick = tick()
local newVCFrame = hrp.CFrame
local a = (shotTick - lastVTick) / (newVTick - lastVTick)
local dummy = Dummy:Clone()
-- somehow simulate what pose the victim had
dummy.CFrame = lastVCFrame:Lerp(newVCFrame,a)
-- blacklist for the victim's actual character
local hit = SimulateShotFor(shooter)
if hit:IsDescendantOf(dummy) then
victim:TakeDamage(--[[damage]])
end
end
You will probably want to store extra data on how the gun was fired, specifically its position/orientation, as well as maybe the CFrame of the victim’s limbs, or otherwise the approximate animation used.
It might not work because:
- It’s guaranteed to have at least a little lag.
- It’s simply not accurate.
This may not actually be ping based, and may actually be based on how Roblox lerp’s its CFrames on default between pings, which is not what we want. How to actually get ping-based CFrames, I have no idea, and deserves an engine feature thread.
You would be able to create ping-based CFrames using a RemoteFunction
that fires to the client and back. Under that structure, a new remote would have to be created for each player since there is no :InvokeAllClients
method:
--on player added(player)
local pinger = Instance.new("RemoteFunction")
while true do
--player might have to return something, idk
pinger:InvokeClient(player)
-- record CFrame and tick here
end
It might still be off because remote functions are round trips, but at least it’s ping-based.