- Home /
ArgumentException: NameToLayer can only be called from the main thread
I was hoping to cache the response of the NameToLayer
function as I suspect it will offer better performance (even if only minimal). Whilst the following source does in fact work, I would like to avoid the warning/error.
public class MyObject : MonoBehaviour {
public static readonly int LAYER_PROJECTILE;
static MyObject() {
LAYER_PROJECTILE = LayerMask.NameToLayer("Projectile");
}
...
void OnTriggerEnter(Collider collider) {
if (collider.gameObject.layer == LAYER_PROJECTILE) {
...
}
else { ... }
}
}
Is there a better approach to this (that doesn't involve storing the layer number in every single object instance?
Note: Error message is only logged when loading scene in editor, there are no problems when compiled.
Answer by syclamoth · Feb 29, 2012 at 01:41 AM
Well, since you are using C#, I can give you plenty of better ways!
For starters, you shouldn't be using the constructor in a MonoBehaviour-derived class, for any reason. Any functionality you put in there should be invoked in the
void Awake()
{
}
method, instead.
If you want to make a lazily-evaluated constant int for the layer, try doing it like this:
int _projectileLayer = -1;
int projectileLayer{
get {
if(_projectileLayer == -1)
{
_projectileLayer = LayerMask.NameToLayer("Projectile");
}
return _projectileLayer;
}
}
Then, you can use 'projectileLayer', and it will only ever calculate the value once per run.
You should avoid using static variables, just on principle- after all, it is possible that you'll want to use the same script to shoot projectiles from several different layers at one point, so storing it in a static variable will limit you in the indeterminite future.
In any case, you're right to try to speed things up- although keep in mind that in the timeless words of Donald Knuth: "premature optimisation is the root of all evil".
I have been using Start
to construct my objects, I will have to look into the difference between Awake
and Start
! I will take that approach, cheers!
First, static constructors are okay as long as you don't use Unity functions. Second, usually you want to perform expensive operations at the start of a scene to reduce hiccups, i.e. avoid lazy loading. Third, the questioner was trying to avoid storing the data separately in each instance.