How FPS games work is there are world models, equipped models and view models.
World models are for weapons that lay on the ground and these are pretty lowpoly. They have physics colliders and pretty much don’t do anything. Low detail. Make them appear and disappear in BGE with addObject() and endObject() when they are dropped, picked up, start/end of a round, etc.
Equipped models are for when you see other people equipping weapons. They are parented to a bone (or in BGE empty that is parented to the bone) of the player character model. No collision, low detail, often you use the same models as world models. Make them initially appear and ultimately disappear in BGE with addObject() and endObject() and then toggle visibility according to what the player has equipped.
View models are the models player can see on his screen. These are cosmetic elements only, to tell the player what he is doing. They are high-poly weapons that are on separate render layer so they don’t interact with the world in any way except sometimes share lighting. In BGE you should make this with overlay scene. Hands are part of the weapon view model and in examples such as CS:source you can find them separately for each weapon view model. Make them appear and disappear with addObject() and endObject() as player gets the weapon or loses it. For which weapon he has equipped you should probably move them away from sight, say downwards by enough of units with a weapon animation (unequip) and turn it invisible just to be sure. Logic is still processed for invisible objects so you need a property for controlling which weapon is active. This sets all the other weapons invisible and moves them out of sight as well as disables any logic being run for that weapon so it doesn’t play the animations etc because it still uses resources even if it isn’t rendered.