1
\$\begingroup\$

When the class hierarchy grows and you deal with a lot of custom types in your project, it sometimes becomes hard to remember which types are allowed to be created via new and which types are derived from MonoBehaviour and therefore can't be created via new but must instead be attached to the GameObject as a Component.

Is it possible to have some safety-mechanism for this? The goal would be to have two base classes to control the ability to use new on a certain type. Ideally resulting in a compile-time error instead of an easy to miss warning in the console ("You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. Blah blah.").

My attempt to make the constructor protected, like this

public class UnCreatableBase : MonoBehaviour {
    protected UnCreatableBase() {
        // using new should be not allowed
    }

    public static T Create<T>() {
        // instead this method allows object creation
        return GameObject.Instantiate (Resources.Load ("Prefabs/" + typeof(T).Name) as GameObject).GetComponent<T>();
    }
}

public class CreatableBase {
    public CreatableBase() {
        // new is ok here
    }
}

still allows me to write:

var whyDoesThisWork = new UnCreatableBase();

I can access the protected constructor even from an outside scope.

Now, the obvious solution would be to make constructors of MonoBehaviour-derived classes private. Manually. All of them. Manually. I was wondering if there's a way of achieving the same in a more generic way.

\$\endgroup\$
  • 1
    \$\begingroup\$ There's no real way to do this that I know of. Generally I name all objects that extend MonoBehaviour as <Something>Component (PlayerComponent for example) \$\endgroup\$ – hobnob Oct 26 '16 at 11:19
1
\$\begingroup\$

The way I lay things out is to have items that exist in the world be Monobehaviours where as supporting processing functionality should be classes. This can further be deliminated by using a C prefix on all processing classes. I.e.

new CCaclualtor(); new CTracking(); new CDateParsing();

GameObject.Instantiate(MyPrefab);

That way, by the type, you know what you should be doing.

\$\endgroup\$

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.