Is it to prevent some kind of bad initialization? But isn’t AddComponent already allowed to be used only in the same places we could change the component’s values anyway? If not, couldn’t the constructor simply be limited to those cases?
In any case, I’m just wondering if we can shorten lines of code. So instead of writing something like this:
Using @dannyskim’s suggestion, about Factory Design Patterns…
I’m using a slightly different way of implementing. I think doing it without reflection (like AddComponent("Initial Value") ) is basically impossible. Just get my GetOrAddComponent code there and see if you can.
So, I’ve mixed up what I wanted with danny’s and this is what I came up with:
public class MyComponent : MonoBehaviour {
string parameter = null;
public static MyComponent CreateComponent (GameObject where, string parameter) {
MyComponent myC = where.AddComponent<MyComponent>();
myC.parameter = parameter;
return myC;
}
The difference here is that I don’t create a GameObject, just like AddComponent does not as well. So you’re expected to pass along one (again, just like the original), to which gameObject is the current one, by code convention.
To see this pattern being put to use in practice you can take a look at my own asset Init(args).
Note that one downside with this system is that the Awake and OnEnable event functions will get called before the Initialize method, so one needs to be careful inside these functions to avoid NullReferenceExceptions taking place (there are ways around this issue as well, but it requires some more complicated code).
Learn to structure your project/code so you don’t need to add any components to gameObjects at runtime, ever.
This way components are initialized from data (serialization system), not code.
Case solved; 0 lines required, 0 cpu/brain overhead.
This is the most basic thing you can do and everyone was doing this at the beginning. But, along the way, something bad happens as programmers feel the need to prove their programming skills by dazzling themselves/others by inventing more and more complex solution to ever unchanging and the most basic program requirements.
Consider this. You can be a hip coder and re-invent a factory pattern to do this:
public class MyComponent : MonoBehaviour
{
MyOtherComponent _myOtherComponent = null;
Text _text = null;
void Awake ()
{
_myOtherComponent = MyOtherComponent.CreateComponent( gameObject , "!ola" );
_text = gameObject.AddComponent<Text>();
}
void Update ()
{
if( condition_is_met )
_text.text = _myOtherComponent.parameter;
}
}
public class MyOtherComponent : MonoBehaviour
{
public string parameter = null;
public static MyOtherComponent CreateComponent ( GameObject where , string parameter )
{
MyOtherComponent myC = where.AddComponent<MyOtherComponent>();
myC.parameter = parameter;
return myC;
}
}
“cool”
OR you can be a stoic chad programmer, that understands that less code & less complexity == better for the cpu, human workhours and, in the end, the project itself:
using UnityEngine;
using UnityEngine.UI;
using NaughtyAttributes;
public class MyComponent : MonoBehaviour
{
[SerializeField][Required] Rigidbody _rigidbody = null;
[SerializeField][Required] Text _text = null;
[SerializeField][Required] MyOtherComponent _myOtherComponent = null;
void FixedUpdate ()
{
_rigidbody.velocity = transform.TransformDirection( Vector3.forward ) * 100;
}
void Update ()
{
if( condition_is_met )
{
_text.text = "hello world";
_myOtherComponent.parameter = "!ola";
}
}
}
TL;DR: expect that all required fields point to valid components, partially or fully configured, end of story.