- Home /
How to use MonoBehaviours inside namespaces.
While reading the "What's new" section on Unity 4.0, I noticed the following:
Scripting: MonoBehaviours can now be inside namespaces.
I then went back to my Unity project, created a simple namespace as follows:
namespace Controllers {
class CharacterController : MonoBehaviour {
[...]
}
}
When trying to attach that component to a GameObject I got an error saying my class was not named the same as my file, even though my file was CharacterController.cs. When removing the namespace definition, it worked fine.
How should I name my files to make it work with namespaces?
Thanks in advance.
Hmm, this won't be a solution to the problem ( At least I don't think it will ), but can you try na$$anonymous$$g the file Controllers. I am wondering if its detecting the namespace as the name.
I don't have a solution either since I'm still on my tablet so I can't test it and I'm still using 3.5 at the moment :)
However the first thing I would suggest is to avoid class names of built in classes in general.
Next thing I would try is rena$$anonymous$$g the file to "Controllers.CharacterController.cs".
In most cases, even in big projects, you don't really need namespaces. If you develop middleware I still would keep components in the global namespace. $$anonymous$$eep in $$anonymous$$d if you want to create a base class which is derived from $$anonymous$$onoBehaviour you can place it in a namespace without any problems as long as the concrete classes have their own file and are in the global namespace.
That's insanity! $$anonymous$$any products on the Asset Store have ridiculous prefixes, when they ought to be in namespaces.
Interesting... I just tested this, and I have no such problem. Namespace seems to work fine. I think it's a useful feature and should be used, we use it in other C# stuff anyway, so why not in Unity?
Btw. when I named the class CharacterController, Unity gave a warning that it has the same name as a built-in, so watch out for that (it works regardless, you just may have conflicts later).
Answer by mtalbott · Sep 25, 2013 at 04:28 PM
I found an interesting querk. While it does work to have a MonoBehavior class inside a namespace, class methods can not use default arguments.
i.e. The following works fine:
namespace TestNamespace {
public class TestClass : MonoBehaviour {
public void TestMethod(string test) {
Debug.Log(test);
}
}
}
however, the following does not work:
namespace TestNamespace {
public class TestClass : MonoBehaviour {
public void TestMethod(string test = "default") {
Debug.Log(test);
}
}
}
I confirm the default arguments bug :( Did anyone file a report about it?
Default arguments in C# were not added until .Net 4.0, which is not supported by Unity.
@TrickyHandz I'm using default arguments with Unity. Of course not in a $$anonymous$$onoBehaviour class but it works in other classes
Answer by ThePunisher · Feb 08, 2013 at 08:43 PM
Could be your class is private to the namespace? Try adding public in front of the class definition.
good observation and the most likely cause, I think.
I've put all my components in namespaces and I can confirm the file needs to have the name of the class without the namespace. Very convenient, too, since the Add Component
- Script
menu gets additional sublevels for namespaces.
Answer by vexe · Mar 25, 2014 at 03:39 PM
I have faced the same issue - however the reason was very peculiar. My script was inside a namespace and it was being identified and seen alright. Then I added a named parameter - which is usually just added to refine code readability, like so:
item = value.Init(@from: this);
Where Init
:
Item Init(Slot from) ...
I removed the named param, and it worked!
However, I was unable to replicate the problem, i.e. create a script inside a namespace and use a named param. I don't know what's special about my case.
Well, I can tell you that you're not crazy, because I had the same issue here. Removing the namespace, or removing the named parameter both fix it. Default paramteres seem to cause the same issue.
Edit: Apparently it's fixed in some unreleased future version. http://issuetracker.unity3d.com/issues/combining-namespaces-mbs-with-default-params-break
Why did you type an @
-sign? `@` is a special character in C# which should only be used in the rare cases that you need a variable named the same thing as a native C# keyword. from
is not a C# keyword (in this context; it can be a keyword in LINQ expression, which you're not using here; see https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ ).
Long story short, you should write item = value.Init(from: this);
. Considering the occasional bugginess of $$anonymous$$ono, it's plausible that the @
was causing the problem, not the named param as a whole.
Named parameters were causing a real issue at the time (@ sign not necessary to cause it) as described in the issue tracker link I posted. It was fixed in Unity 4.5 though and as far as I know has been fine since.