I use simplecast
Whats the best way to go about with adding suppression effects with a gun (while the cast is active, not when it hits an obj)? I cast everything from the client btw
I use simplecast
Whats the best way to go about with adding suppression effects with a gun (while the cast is active, not when it hits an obj)? I cast everything from the client btw
I’m not entirely familiar with simplecast and I am not familiar with your implementation but I will share what I am thinking of off the top of my head…
If there is an event that fires each time the cast is updated (bullet moved), you could do a query with WorldRoot:GetPartBoundsInRadius(pos : Vector3, radius : number, overlapParams : OverlapParams)
to see if any player are within the radius you set of the projectile. If they are then execute your suppression code.
Do you think that’d be the most performant way? I’m really only concerned about optimization, as this wouldnt be a completely integral feature
i’m assuming you have the enemy players’ bullets available on the client you are trying to get suppressed
a simple distance check(IF THE BULLETS ARE MADE OF MULTIPLE RAYS) would work but wouldnt be like world class optimization but thats what i’d do
if it’s just a singular ray, you could compare the ray’s direction to the direction from it’s origin towards the target, and that would be a sort of measure of nearness
there’s also solving for the nearest point on a ray to another point, which is more difficult vector math if you’re up to it(google it)
I dont know if this is a good idea at all… but I did it on the client?
local function OnCastMove(self, castData, oldVec, newVec)
for _, player in ipairs(game.Players:GetPlayers()) do
if player ~= Player and player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
local playerPosition = player.Character.HumanoidRootPart.Position
local distance = (newVec - playerPosition).Magnitude
if distance < 10 then
print(player.Name .. "in range")
end
end
end
end
it would be better to do it on the client being suppressed so that way you don’t have to deal with extra delay or looping though players
it would fit right in with tracer replication(unless they are serversided(yuck))
I’ve approached it a couple of ways but I’m not sure how effective they are:
--Vector based approach
function SimpleCast:_update(dt)
debug.profilebegin("SimpleCastUpdate")
local timeNow = os.clock()
local overlapParams = OverlapParams.new()
overlapParams.CollisionGroup = "Players"
local players = game:GetService("Players"):GetPlayers()
local activePlayers = {}
for _, player in ipairs(players) do
if player.Character and player.Character:FindFirstChild("HumanoidRootPart") then
activePlayers[player] = player.Character.HumanoidRootPart.Position
end
end
for index, cast in ipairs(self._casts.Cache) do
cast.LifeTime = timeNow - cast.StartTime
local newPosition = SimpleCast.GetPosition(cast.LifeTime, cast.InitVelocity, cast.InitPosition, self._gravity)
local oldPosition = cast.Object.Position
local hitObj = self:Raycast(oldPosition, newPosition, 1)
for player, pos in pairs(activePlayers) do
local dist = (pos - newPosition).magnitude
if dist <= 10 and player ~= cast.Caster then
print(player.Name)
cast.DetectedPlayers[player.UserId] = true
end
end
if timeNow >= cast.StartTime + 10 or oldPosition.Y <= workspace.FallenPartsDestroyHeight then
self:CastTerminate(cast)
continue
end
if hitObj then
self._onCastHit(self, hitObj, cast, newPosition)
continue
end
cast.Object.Position = newPosition
end
debug.profileend()
end
-- @Seiiyo inspired approach
function SimpleCast:_update(dt)
debug.profilebegin("SimpleCastUpdate")
local timeNow = os.clock()
local overlapParams = OverlapParams.new()
overlapParams.CollisionGroup = "Players"
for index, cast in ipairs(self._casts.Cache) do
cast.LifeTime = timeNow - cast.StartTime
local newVec = SimpleCast.GetPosition(cast.LifeTime, cast.InitVelocity, cast.InitPosition, self._gravity)
local oldVec = cast.Object.Position
local hitObj = self:Raycast(oldVec, newVec, 1)
local nearbyParts = workspace:GetPartBoundsInRadius(newVec, 10, overlapParams)
for _, part in ipairs(nearbyParts) do
local player = game:GetService("Players"):GetPlayerFromCharacter(part.Parent)
if player and (player ~= cast.Caster or player ~= self._caster) and not cast.DetectedPlayers[player.UserId] then
cast.DetectedPlayers[player.UserId] = true
end
end
if timeNow >= cast.StartTime + 10 or oldVec.Y <= workspace.FallenPartsDestroyHeight then
self:CastTerminate(cast)
continue
end
if hitObj then
self._onCastHit(self, hitObj, cast, newVec)
continue
end
cast.Object.Position = newVec
end
debug.profileend()
end```
between the two approaches you used, I would advise against the GetPartBoundsInRadius because that is almost definitely slower for the same result
it would be surprising if the profiling results prove otherwise
Actually, ive found a better way to do it:
the owner of SimpleCast suggests when replicating the cast, you should create and fire a different cast from the receiving clients.
Understanding this- I just modified the _update function. It subtracts caster’s rootpart magnitude from the distance of the castobject, and if within 15 studs, then i handle the effect there.
Thanks regardless tho
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.