Through my 10 year game dev career I did find that people tried to solve the singleton dependencies by passing a chain of dependencies in which you dig for what you need. And your arguments are very strong that you try to cut it as close to the line where you need it as possible.
About the gun to rounds thing. I think the main issue there is that you assume the gun / ammo type.
I would try to design it as in that I have a UI for rounds (gun), charge (lazers) and durability (melee). Then I would, or use the composition (gun.GetComponent()) or use casting (gun is LazerGun) to determine which of the 3 UI types I wish to enable.
I would do this by having the UI itself be responsible of telling me they want to render the UI. This with a GunUI.CanRenderGunType(gun);
where they can determine if the gun applies for what they want to render by getting components, name etc.
Maybe you want a very specific gun UI for the special boss gun, you can by adding a new GunUI that is very specific
Then it can dig for what it needs out of it. So in that regard I think The Law of Demeter does not fully apply. You can’t get around assuming / requiring things, but they have to be narrowed down to the most specific level possible. (Single responsibility == single dependency)
Thank you for the nice insights. I am enjoying the course. A nice refreshment and a good way to re-evaluate what I already know.