There’s not really much you can do to optimize it I believe.
also it’s not AI
There’s not really much you can do to optimize it I believe.
also it’s not AI
I have question about the AI and gun usage
Is the bullet hitscan? – if so you dont need fastcast
Are you rendering bullets on the client? – usually render stuff on the client and not on the server for better performance
You also dont have a Caster.CastEnd or whatever the destroy part of the ray is so you are only returning the part IF it hit also
if result.Instance:FindFirstAncestorWhichIsA('Model'):FindFirstChild('Humanoid') then
local enemyHum = result.Instance:FindFirstAncestorWhichIsA('Model').Humanoid
enemyHum:TakeDamage(5)
end
can be
local enemyHum = result.Instance:FindFirstAncestorWhichIsA('Model'):FindFirstChild('Humanoid')
if enemyHum then
enemyHum:TakeDamage(5)
end
the edit was cause i accidentaly submitted it too early
Render the bullets on every client not the server do that by using FireAllClients
on an RemoteEvent.
Remember to protect your RemoteEvents!
Also one quick thing to note please use Animator:LoadAnimation
and PivotTo
instead it will most likely improve performance with your code!
Sorry about that, the script is included in an AI named ‘Conscript’, that is why I mentioned it.
The bullet isn’t really hitscan, my AI.Gun script casts one raycast (without fastcast) to check if a player is in sight, and if it isn’t, it fires an inefficient pathfinding script to get closer to the player, then the local function ‘Fire’ is fired which does FastCast:Fire() which fires a partcache bullet at the player.
I am not rendering bullets on the client, would it make a difference as the ai will always be visible by the player pretty much and it would be a pain to make it client based, I would probably have to spend atleast a whole day debugging the mess that it would create.
thanks for the Caster.CastEnd tip though! I will implement that in right now.
animator:LoadAnimation()? Is that located in the humanoid? Thanks for the tip, but again, I am skeptical about migrating this whole script to the client, would that make a big impact?
Yes it is located in the humanoid. And yes it would make a big impact!
Hi, sorry for not marking your post as the answer, I am just waiting for a response on this dev forum post to see if it reduces the lag, I will mark your post as the answer once I get an answer on this post (god that was confusing to say), thanks again.
Sorry, but it didn’t work, I tried rendering fastcast bullets and doing everything on the client, but that just made it much worse, here is a video showing the performance:
--edit: this is a local script
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local Remotes = ReplicatedStorage.Events
local Event = Remotes[script.Name]
local FastCast = require(ReplicatedStorage.FastCastRedux)
local PartCache = require(ReplicatedStorage.PartCache)
ReplicatedStorage.Events.FastCastClient.OnClientEvent:Connect(function(NPC,Type,attachment,direction,velocity)
if Type == 'Constructor' then
local Caster = FastCast.new()
local behaviour = Caster.newBehavior()
local raycastParams = RaycastParams.new()
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.FilterDescendantsInstances = {NPC,workspace.Projectiles,workspace.OreSpawningArea}
local bulletTemplate = Instance.new('Part')
bulletTemplate.Size = Vector3.new(0.2,0.2,12)
bulletTemplate.Material = Enum.Material.Neon
bulletTemplate.Color = Color3.fromRGB(255, 225, 0)
bulletTemplate.CanCollide = false
local CachedBullet = PartCache.new(bulletTemplate,100,workspace.Projectiles)
behaviour.RaycastParams = raycastParams
behaviour.MaxDistance = 300
behaviour.AutoIgnoreContainer = false
behaviour.CosmeticBulletContainer = workspace.Projectiles
behaviour.CosmeticBulletProvider = CachedBullet
Caster.LengthChanged:Connect(function(cast,lastpoint,direction,length,velocity,bullet)
if bullet then
local bulletlength = bullet.Size.Z/2
local offset = CFrame.new(0,0,-(length - bulletlength))
bullet.CFrame = CFrame.lookAt(lastpoint,lastpoint + direction):ToWorldSpace(offset)
end
end)
Caster.CastTerminating:Connect(function(cast)
local cosmeticBulletObject = cast.RayInfo.CosmeticBulletObject
if cosmeticBulletObject ~= nil then
CachedBullet:ReturnPart(cosmeticBulletObject)
end
end)
Caster.RayHit:Connect(function(cast,result,velocity,bullet)
local enemyHum = result.Instance:FindFirstAncestorWhichIsA('Model'):FindFirstChild('Humanoid')
if enemyHum and result.Instance:FindFirstAncestorWhichIsA('Folder').Name == 'Allies' then
ReplicatedStorage.Events.FastCastClient:FireServer(enemyHum,5)
end
end)
function Fire(firepointAttachment,direction,velocity)
Caster:Fire(firepointAttachment.WorldPosition,direction,velocity,behaviour)
end
elseif Type == 'Fire' then
Fire(attachment,direction,velocity)
end
end)
I am stuck, I have no clue what i’m doing wrong, I tried doing partcache on the server and sending it to the client, it didn’t work, I tried doing things on the server and only doing rendering parts on the client, it didn’t work, I have no clue what to do, please advise me on things I can do to get an answer on this issue, how to write a dev forum post better so that it gets a reply, I just want to get this thing done
Hmmm… I am making a Gore System in the meantime however afterwards I will focus on one of my most important projects which is titled: RenderingService you can render objects in a VPF and in theory it should reduce lag greatly objects such as: Bullets, Bulletholes, Blood, etc.
You’re creating a new caster for everytime the client makes the bullet, there should only be one caster. In the FastCast API, it only states that it should act as the entire gun or projectile system and not a bullet
That is why I send an event with the ‘Type’ of constructor every time an npc is created, to build the caster once and then I send the ‘Type’ of Fire whenever I want the npc to fire, it sounds confusing but I am not making a new caster every time an npc fires, here is a picture showing the results of what happens when I add ‘print(new caster created!)’ on top of the ‘if Type == ‘Constructor’ then’ and spawn 20 npcs:
would making a single caster for 20 or more npcs work?
How I do it is i create a server side module which does all the calculation and damage and have the client do all the visuals and stuff
Server side
local module = {}
local fastcast = FASTCAST
local caster = fastcast.new()
local castBehaviour = fastcast.newBehaviour()
local projectileVisualizer = YOUR REMOTE EVENT
function module.fire(origin,direction,velocity,acceleration,distance,raycastparams,projectile)
castBehaviour.Acceleration = acceleration
castBehaviour.MaxDistance = distance
castBehaviour.RaycastParams = raycastparams
caster:Fire(origin,direction,velocity,castBehaviour)
projectileVisualizer:FireAllClients(origin,direction,velocity,acceleration,distance,raycastparams,projectile)
end
caster.RayHit:Connect(function(...)
do your damage stuff here
end
return module
local fastcast = FASTCAST
local caster = fastcast.new()
local castBehaviour = fastcast.newBehaviour()
local projectileVisualizer = YOUR REMOTE EVENT
projectileVisualizer.OnClientEvent:Connect(function(origin,direction,velocity,acceleration,distance,raycastparams,projectile)
castBehaviour.CosmeticBulletTemplate = projectile
castBehaviour.CosmeticBulletContainer = workspace
castBehaviour.Acceleration = acceleration
castBehaviour.MaxDistance = distance
castBehaviour.RaycastParams = raycastparams
caster:Fire(origin,direction,velocity,castBehaviour)
end
caster.LengthChanged:Connect(function(cast,lastpoint,direction,displacement,vel,part)
part.CFrame = CFrame.new(lastpoint,lastpoint + (dir*displacement))
end)
Honestly, theres probably much more efficient ways to do this but this has always worked for me. Doing all the damage calculations on the server also makes it more secure
Honestly I don’t know what to do anymore
edit: now I am casting 3 rays at once instead of a single one on the client
edit: the script itself isn’t lagging really, it spikes massively when the player respawns/gets targetted by the ai by about 4%, it seems to sit at a stable 2% when the player isn’t targetted.
edit: not really I am going insane I have no clue what to do
Yeah I somehow need to handle like 600 or 700 raycasts (and projectiles (in this case using fastcast and partcache)) every second, and I know it is possible, but I am at a loss, and this topic died
I’m gonna start working on the module now!
did you end up finishing that module? just checking lol
You will definitely need to use parallel lua for that amount of raycasts (every frame?). You might be able to get all those to run at 60 fps on most devices, but, why do you need that many raycasts?
No, I never did finish it, I abandoned the project like a year ago after I couldnt fix the performance issues sadly.
I think you can’t really optimize it without modules. yes i love them.