I’ve been using zay-es for all of my projects for more than 2 years now and I have tried a lot of different approaches for implementing weapons. I have honestly not been happy with any of the approaches I have taken, so I was interested in any thoughts on implementing them?
Most of the time my weapons are vehicle weapons, so we’ll use 2 examples: a machine gun and a guided missile launcher. Both are fixed-mounted only shooting straight forwards.
The parent vehicle will usually have a Transform component.
The machine gun has always been relatively easy to implement. I have an entity with a ChildOf(entityId) component, a Weapon(rof, string(asset or script)), and a Trigger component.
During the update the weapon system will first make sure the rof of the machine gun is primed, then it will check if the trigger is active. The hard part is what follows:
Question 1: Is it better to then have the weapon get the transform from it’s parent (entityData.getComponent(parent, trans)), or is it better to have a state that copies the parent transform onto it’s children? I have usually looked “up” to the parent and grabbed the transform either through entityData.getComponent, or I will store an entity set of parents with either a filter or a component to signify which ones have child weapons.
Once I have the transform in some fashion, I will create a new entity and attach all the required components. I have used scripts that passed all the data to the script and let the script do what it needed, and I have loaded assets via xml files.
Question 2: For regular bullets with few components, would you recommend using a script that has access to the entity data and it’s parents components or load an asset and apply the dynamic components to each projectile entity in the same way. For regular bullets, ultimately all that needs done is to transform the bullet to the correct spawn location, attach all the bullet components (physics, damage, collision, etc) and send it on it’s way.
Finally this leads to my current predicament: guided missiles. I currently have a sensor(fov, maxRange) component, and a target(entityId) component. The sensor state simply finds an entity that can be targeted that is within the fov and max range of the sensor, and applies the target to the sensor entity. I am at a loss as to the best location for these systems though.
Question 3: Does the vehicle hold the sensor, and therefor also the current target. If so, the weapon would need to “look up” to find the active target before firing. Or do the individual weapons hold the sensor, therefore allowing different weapons to have different targeting behaviours, but now the weapon needs enough information for the sensor to function (namely a transform component)
I am mostly looking for advice on best practices as I have said, I have implemented all of these several times before and every time I have tried a different approach, but they always seemed janky in the end. I am currently having the most trouble trying to wrap my head around where the missile logic should live.
Bonus Question: Should missile logic be divided into the ECS as many components that make up a functioning missile, or should I revert back to methods I’ve used in the past and leave as much functionality as I can to scripts that will be evaluated every frame (groovy class loader is surprisingly performant but I am sure there is a limit). Currently all my missiles need to track a target is the target(entityId) component and a missileSeeker(marker) component. The missile seeker system currently just checks the missile transform and influences the missile via a driver, which works back through the physics system.
Thanks in advance for any advice or ideas