What exactly happens when a MonoBehaviour is created with new?
I'm aware that it's "not allowed"; I did this by accident and it will thoroughly be removed from my final build. Obviously there's a good reason for that rule.
The weird thing is, it's in a unit testing component, and it still works perfectly in spite of the warning. I was filling a list with a few constructed instances of a class inheriting from MonoBehaviour, just to ensure that a function was doing what I wanted it to do, and I get this warning; but the test seems to run fine. Additionally, this is a warning, not an true error, which likely also has a reason.
Out of curiosity, as my understanding is clearly incomplete, can someone explain, and if possible provide a link to documentation explaining, why it is that Unity does not allow a behavior which it is clearly quite capable of? Why does it forbid this, and, in the event that the warning was ignored, what would be the drawbacks?
Thank you for completing my comprehension of it.
Unity has a component-based architecture. Any object that exists in a scene is represented by a GameObject
which has one or more Component
objects attached to it.
Components frequently change the behavior or appearance of the GameObject that they are attached to. In some cases, Components also reference or depend on each other. As an example, RigidBody
and Collider
components tend to be used in tandem.
MonoBehaviour
scripts are also derived from the Component
class. You can potentially create a behavior object using new
, but it won't be attached to any GameObject and therefore won't properly exist in the scene. This is likely to lead to errors:
- Built-in events may not work consistently. For example,
Awake
,Start
,Update
, orOnCollisionEnter
. - Built-in references won't work at all. For example,
gameObject
,transform
, or theAddComponent
andGetComponent
family of functions. - Unsafe for other components to interact with this component in a standard way.
- Scene transitions are likely to compound the problem, since your orphaned script won't be attached to anything in the scene.
You do have some other options, though.
You can create a new GameObject, and then attach your script to it. This is a common workflow for scripts that will be managing game state for an entire scene (or across multiple scenes). This may fall under a singleton pattern.
You can also create classes that do not derive from MonoBehaviour
, if you need those classes to be usable outside of a scene.