The friendly fire is a good concern, I didn't think about it, but then again, I'm not sure how a weapon reference will help you with that, you actually need a player reference to know who fired it, unless each weapon can only be used by a group of players of the same team.
In my previous project, I would create a finite number of weaponComponents as children to my ship. Each of them would swap content based on what weapon was equipped. I agree that passing the "owner" of the weaponComponent to the bullet through that particular line of logic was very crappy. I think I stashed a controller reference that basically went something along the lines of weaponComponent.getShip.getController (my eyes are bleeding)
The sound as part of the bullet looks weird, I'd play the sound as part of the the weapon, not as part of the the bullet. I don't know much about weapons and bullets, so maybe the weapon and the bullet combination does change the sound, but most of the times a firing sound for each weapon is enough.
Actually, it would need to occur at a higher level. If it was a "per weapon" trigger, I'd end up with sounds overlapping unnecessarily (and sounding louder) when more than one weaponComponent is triggered by the same input. I ended up firing a message and catching it in the audioController instead to avoid duplicates.
If you'll create complex bullets maybe you can use the factory design pattern, it let's you encapsulate the creation of objects in a more flexible way.
I've always been hesitant to jump into Factories because I met a Tech Director that told me they were "crap". Now, obviously, I'm always careful when I am not given any reason, but given I generally respect his opinions as far as tech stuff goes, I figured there might be a reason to avoid these?
About the last paragraph, you need a reference to each bullet object? Why do you need all that information? The bullets will always be there in the game even after hitting something or leaving the play field? Can't you just have some counters and stats instead?
I don't believe I'll need this, but I did in my previous prototype because I needed to find a way to cleanly dispose of dead bullets in HTML5. Now, obviously, Unity is far more permissive and I can just call a destroy on self after calling for an explosion and this allows me to cleanly dispose of bullets that have outlived their own use.
About that infinite reference you mentioned, you don't have the references repeated, what you mentioned was a navigation through the same objects, but the references are always the same, you don't need more ram or resources when something like that happens. But, even if it's not a problem, sometimes it's a sign of overcomplicating the design, making things know each other when you don't really need that. I still think that, if I was working with weapons and bullets, the bullets would not know about the weapons. I've made a simple shoot em up this way some months ago and it worked, even avoided the friendly fire setting a flag on the bullet to know if I shooted it.
Thanks, that helps, and you're probably right!
Anyway, you mentioned the reference as a parameter on the constructor, but you are not forced to keep the reference to the weapon forever. You can use it to initialize other fields and forget about it. Think about it, if you fired a bullet, the bullet only needs the damage of the weapon at the time it was fired. This way, if the weapon damage increases while the bullet is in the air, the bullet is not affected.
Yes, I believe that is where I was headed with solution A: pass it as an argument to the constructor, but strip it down in the constructor to stash references to values I actually intend on using, and not actually stash a reference to the actual weaponComponent locally. This allowed me to limit the amount of arguments I'd pass to the constructor and felt like it would result in more readable code:
A: Argument: weaponComponent
Stripped down into various variables during constructor
only these vars ever get used by the bullet
B: Argument: all vars I intend on using from the original weaponComponent
Constructor bridges all arguments to local vars
A felt cleaner, but you seem to be hinting at B?