I have a whole inheritance tree of game object types I need to be able to instantiate, activate and deactivate (or enable and disable) at run time, and I want to be able to use constructor parameters when I instantiate them so I don’t have to use a bunch of boilerplate code every time I do that. That grows in size with each level in the inheritance tree. =P
What I’ve resorted to is (this seems kind of embarrassing and awful), I’ve created a single behavior script, which has a reference to the base class for my inheritance tree. So it has Update(), FixedUpdate(), OnTriggerEnter(), etc., and those functions just pass along those events to the same functions of the referenced object. So I assign that single behavior script to every prefab. So that way I can instantiate my objects with constructor parameters however I want to. The base class constructor constructs a prefab of a passed in name, gets the script component and sets the reference to itself, and sets it’s own gameObject and transform properties, et etc, just to make things easier in the subclass code. But then I have to call GameObject.Instantiate(…) instead of just Instantiate(…), and do a few other less-than-optimal things like that. So this approach seems a bit clumsy and rigid to me. I’ve got a whole inheritance tree of objects which basically represent the behavior scripts for prefabs, but they’re not monobehaviors. Seems kinda wrong.
Hmm, what about this: I create a base class that extends monobehavior. Then I derive my inheritance tree from that. Each subclass has an Initialize(…) function that does what my current classes do in their constructors. So… I would assign one of my subclasses to a prefab, then where ever I consume that, I instantiate the prefab instead of the class, and then get the script component and call the Initialize(…) function. Meh. Still too much code per consumption.
Ok, maybe instead of having an Initialize(), or in addition, each subclass has a static Instantiate(…) function that instantiates the prefab, gets the script component, and sets the various variables or calls it’s own non-static Initialize(…) to do that. Tch, but then I basically have a version of my current base class constructor for every subclass. In fact I would have a bunch of multipli-duplicated code in that Instantiate function.
Could I mutate Instantiate(…) and pass the prefab name up the inheritance chain like I do now in the constructors? Let’s say Instantiate(…) returns the script component, so the base class would return that to the subclass, and so on down the chain. Can I recast that as the subclass in the subclass’s Instantiate(…) so I can do further initialization? Maybe pass parameters to a mutated Initialize(…) instance function, so I don’t have to prefix everything with “theobject.”…
That seems like that could be a reasonable solution, if it works.
I dunno, what do you do? How do you handle the need for constructor parameters? Is there some easy/obvious/“right” way to do this that I’m missing?
If what I’m gathering from reading answers from some of you more Unity-experienced people is correct, it seems like a lot of you don’t really use anything analogous to constructor parameters, in fact you may not really use inheritance at all. Yet you feel your code is easy to create and maintain? It’s like there’s some kind of paradigm or pattern that I’m not quite getting. Involving assigning multiple different behavior scripts to a single prefab, for example. Kind of an “I’m a this, but I’m also a that, and I have this modifier, too” kind of a thing. So the set of scripts is basically flat, or as flat as possible, and each one is… well, tries to be small. But you might end up with 5 different Update() functions associated with a single prefab. (!?) So I think I sort of get that, but I still don’t see how, doing that, you avoid ending up with quite a lot of basically-duplicated-but-slightly-different code sitting around in various places. And what about all the potential for stepping on each other’s toes that all those different shavings-of-behavior have? There would be this mass of rapidly-fading-to-gray knowledge of which ones can be mixed with which other ones. Seems like you’d have to be some kind of gestalt genius to pull that paradigm off very well for very long. Either that, or you’d evolve some kind of organizational system for naming them and placing them in the assets tree or something, that makes it clear which ones can be used with which other ones. But then aren’t you basically back to a hierarchy at that point?