3
\$\begingroup\$

Here's what I have in our little Unity game:

  • If an asset (mostly a prefab or a texture) has to be accessed (e.g. to instantiate a game object), it is often passed as [SerializeField] to the script component. Scripts that are not components get their assets through the constructor so the assets are passed down until the class where they are needed. It's ugly.
  • If a lot of assets are needed (like textures of an animation), they are moved into a folder called "Resources" and accessed through the Resources class. The documentation explicitly says "don't use it".

What I want:

  • To access assets through a name or path to create objects at run-time.

What I found:

  • The AssetDataBase class looked promising until I couldn't locate it and found out it is deprecated (and the documentation does not tell how to replace it).
  • Nothing on Google but a lot of outdated things
  • Asset bundles look promising too, but they are quite complicated and there are no really good migration tutorials and I don't know how to use them.

Any suggestions? How do small/mid sized/bigger Unity games handle their resources?

\$\endgroup\$
1
\$\begingroup\$

There are a few main ways to handle dependencies:


1) Make the scripts handle their own dependencies.

This seems to be what you're doing, and is how most beginner programmers first learn to handle dependencies. It is probably the most intuitive way to do it, to a programmer familiar with passing parameters to methods, but not familiar with other methods of dependency handling.

As you are finding out, it quickly becomes apparent that it has many limitations on anything more advanced than classroom assignments or the simplest kinds of applications.


2) Dependency-handling using Singletons - The art of making scripts with a simple global access point, responsible for holding all the dependencies throughout the project.

This is usually done using singletons as holders, and then "pulling" references from those singletons using

Singleton.instance.dependency1

Where:

  • Singleton is the type of the class.
  • instance is a static field in that class, holding a reference to an (the only) instance of that class.
  • dependency1 is a field holding a reference to one specific dependency.

You will often hear that "singletons are evil" or that "you should never use singletons". Don't blindly trust such statements. As often is the case where similar generalized statements are involved, things are not so black-and-white.

Singletons do have their use-cases, and, although there are better methods for handling dependencies, singletons are a valid method, and they are an important stepping-stone to understand why other, better methods, are better.

I personally use singletons for many of my small-scale unity projects; finding more advanced methods more time-consuming for "advantages" that would never be used/required (aka overkill).


3) Dependency-injection (basically, singletons, but with Inversion of Control steroids):

This is pretty much the experienced programmers' standard way of handling dependencies. It does, however, present a steeper learning-curve in general (nothing too complicated, but you probably don't want to learn this while at the same time learning to make your first games).

Additionally, for Unity specifically, there are some caveats, which make DI really not appropriate for your first few projects. And if you don't step through dependency-handling based on singletons first, you will know what to do, but most likely, you will be doing DI without knowing why it's (most but not all times) better to do dependency-handling this way.

The easiest way of doing DI for Unity, at least to my knowledge, is like doing DI for any other project: Use a DI framework.

In Unity's case specifically, the one I have experience with and recommend is Zenject. You can also find explanations for everything I mention here on the Zenject project page. From the theory behind DI, to the caveats related to Zenject (and DI in general) on Unity.

\$\endgroup\$
  • \$\begingroup\$ Can you please add an example of how the singleton would load a specific dependency, like a texture or prefab? How does such a class look like in your projects? \$\endgroup\$ – piegames Dec 13 '17 at 10:13
  • \$\begingroup\$ @piegames Take a look at the community's singleton implementation. It can be improved further, but it works out of the box and is a good reference point if you decide to roll out your own implementation. \$\endgroup\$ – XenoRo Dec 13 '17 at 15:15

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.