0
\$\begingroup\$

Problem

Whenever a player is added to the game (in the form of the server instantiating a player Game Object with a Player component), I want to provide it to every script that needs a reference; in other words, dependency injection.

Potential Solutions

I thought I'd create an IPlayerRequester interface and have the Player script look up all implementing scripts on the client when it's created, but Unity has no interface-searching equivalent of FindObjectsOfType<>().

More Info

The game is multiplayer, where 1 player is the host — a client and the server — that is joined by other clients.

I'm using Mirror.

When a new client is added, the Player script's (that was just spawned) callback OnStartLocalPlayer() is invoked, and so far, that's the only way I've found to access the local environment.

But because this is the same Player that I'm trying to inject into requesting scripts, I can't just raise an event in that method, so that's out.


What would be a good solution here?

\$\endgroup\$
16
  • \$\begingroup\$ Unfortunately I've run into this problem a few times myself. Unity really doesn't have a good solution for this. You can get all objects that implement an interface from Resources but this will also include prefabs and can open you up to some horrifying bugs. \$\endgroup\$ Oct 29 '20 at 8:01
  • \$\begingroup\$ Depending on how many interfaces you have and if one GO can have only one interface, you could tag them and use GameObject.FindWithTag(). \$\endgroup\$
    – Zibelas
    Oct 29 '20 at 8:03
  • \$\begingroup\$ @Zibelas Sadly, given that I'm doing this to lessen dependency and clean up the code, that sounds like it half-defeats the purpose. \$\endgroup\$ Oct 29 '20 at 8:05
  • \$\begingroup\$ Addition to 2), what about a dictionary with <InterfaceName, List>? At least you don't need to create a new list for each new interface though you still have your singleton \$\endgroup\$
    – Zibelas
    Oct 29 '20 at 8:16
  • \$\begingroup\$ You can create a class or abstract class and implement your interface, and inherit from it, but than you wouldn't be able to inherit from multiple of your interfaces. FindObjectsOfType works with classes and abstract classes. You can avoid using FindObjectsOfType<Monobehaviour>() by keeping a list, adding removing on spawn and destroy. And filter that list. That might give you some performance benefit. \$\endgroup\$ Oct 29 '20 at 8:19
-2
\$\begingroup\$

you can create a List of players:

List<Player> players;

and use it for a group them all and iterate with a loop to apply them some operations. can play with it + the constructor to setting up all the stuff.

if it doesn't work u got delegates + events (a bit more advanced)

(Im not Unity dev but hope it helps)

\$\endgroup\$
2
  • \$\begingroup\$ The explanation's not entirely clear. Could you elaborate? \$\endgroup\$ Oct 29 '20 at 17:03
  • \$\begingroup\$ you must know C# programming. \$\endgroup\$
    – user406126
    Oct 30 '20 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.