Using namespace in Unity hides functionality - c#

Using Unity 5.4 beta with Hololens, setting a class within a namespace disables some UnityEngine functionality.
If I declare a class, it all works fine. If I wrap it inside a namespace, classes don't see each other, even within the same namespace or with the using addition.
Making a class MonoBehaviour, I can drag and drop it onto a game object, if I wrap that class inside a namespace, Unity complains that it is not a MB or it has issue so it cannot be dragged.
Does anyone have similar issue? Just asking before reporting bugs since 5.4 is still beta.

Classes don't see each other because you are not importing them or accessing them through their namespace. To access anything in a namespace, you must import the namespace or call the namespace followed by the class name. Check below for both examples.
Class with namespace:
namespace MyANameSpace
{
public class A
{
}
}
In order to see class A, you have to import it with the using keyword.
using MyANameSpace;
public class B : MonoBehaviour
{
A a;
// Use this for initialization
void Start()
{
a = new A();
}
}
Another method is to access them directly through the namespace.
public class B : MonoBehaviour
{
MyANameSpace.A a;
// Use this for initialization
void Start()
{
a = new MyANameSpace.A();
}
}
If this does not solve your problem, then you have to post your code. That's likely not a bug.

I managed to figure out what I think is happening. Here is what I had:
namespace Company.Hololens
{
public enum GazeState
{
None = -1, NoHit, Hit
}
public class CursorEventArg : EventArgs
{
}
public class CursorController : Singleton<CursorController>
{
}
}
and it seems as if Unity does not like the order of class declaration. Pushing the EventArg down to the end of the script and it goes fine.
Not sure if this should be considered a bug, I have never seen any mention of class declaration order. Declaring an interface on top is fine though.

Related

Unity Topology & CS0101

Hey, so I've stumbled upon this little logistical issue. I can't find any actuall solutions to this specific use case, so I've created this simple example:
Imagine a simple sketch of a UI element in a game.
As you can imagine, this panel shows a popup that shows all the rewards and keys needed to unlock the chest.
It consists of multiple elements, and as these elements are repeated, it's a good practice to separate them. So let's say I Separate them into three different Monobehaviour classes, each having its own file.
TreasurePanelUI: The main panel element that houses references to all non-repeating UI elements.
Reward: A sub-element of the TreasurePanelUI, it houses references to its own elements (Image of the item, Text reference for the name, etc.)
Lock: A sub-element of the TreasurePanelUI, it houses references to its own elements (Image of the Lock, effects, animations of unlocking the lock, etc.)
So here comes the issue, how do we divide their namespaces? Well, here is my idea:
The dominant TreasurePanelUI may look something like this:
namespace UI //The class is a UI element.
{
public class TreasurePanelUI: MonoBehaviour
{
//Neat code...
}
}
And the other two elements may look something like this:
namespace UI.TreasurePanelUI //The class is a UI element but also part of TreasurePanelUI.
{
public class Reward: MonoBehaviour
{
//Neat code...
}
}
and
namespace UI.TreasurePanelUI //The class is a UI element but also part of TreasurePanelUI.
{
public class Lock: MonoBehaviour
{
//Neat code...
}
}
Seems logical right? Well, here's the problem: It won't compile.
This will throw a CS0101. Meaning our class name is clashing with the namespace name.
My main question is, is there an alternative way of achieving the same code topology that will actually compile?
Also, feel free to point out if my approach or my topology/method is entirely wrong! haha
I don't think you should use the same names for classes and namespaces, because (like it happened to you) they might clash.
The C# doc comes very close to discouraging what you are doing.
DO NOT use the same name for a namespace and a type in that namespace.
For example, do not use Debug as a namespace name and then also provide a class named Debug in the same namespace. Several compilers require such types to be fully qualified.
Source
I would suggest to just put all the classes in the UI.Treasures namespace.
You already got this answer when you asked this exact same question yesterday.
Your code does not run because UI.TreasurePanelUI is an ambiguous call - is it the namespace for the other classes or is it the TreasurePanelUI class?
Like I told you in your other question - just rename your TreasurePanelUI class.
If you're looking for a list of alternatives then I think that's off-topic, but you could make the other classes subclasses of your TreasurePanelUI class, like:
namespace UI //The class is a UI element.
{
public class TreasurePanelUI: MonoBehaviour
{
//Neat code...
public class Reward: MonoBehaviour
{
//Neat code...
}
public class Lock: MonoBehaviour
{
//Neat code...
}
}
}
Now you can access UI.TreasurePanelUI.Reward or whatever. If you don't want them all in the same file you can use the partial class, like:
namespace UI //The class is a UI element.
{
public partial class TreasurePanelUI: MonoBehaviour
{
//Neat code...
}
}
namespace UI //The class is a UI element.
{
public partial class TreasurePanelUI: MonoBehaviour
{
public class Reward: MonoBehaviour
{
//Neat code...
}
}
}
namespace UI //The class is a UI element.
{
public partial class TreasurePanelUI: MonoBehaviour
{
public class Lock: MonoBehaviour
{
//Neat code...
}
}
}
But really, the best thing you can do it to just change the name of your TreasurePanelUI class. If it's a base canvas or base element then you could have
namespace UI.TreasurePanelUI //The class is a UI element.
{
public class BaseCanvas: MonoBehaviour
{
//Neat code...
}
}

Unity3d no Monobehaviour scripts in the file, or their names don't match the file name

Hello everyone I've been working on my first game and suddenly I got this error and cannot run the game, I already installed the new version of unity but it persists. I see it can be caused for several reasons but had no luck so far, do you know the most probable causes and how to fix it?
When I select the scripts the only one where I do not get this error is the following:
using UnityEngine;
using Assets.Code.States;
using Assets.Code.Interfaces;
public class StateManager : MonoBehaviour
{
private IStateBase activeState;
void Start ()
{
activeState = new BeginState (this);
}
void Update ()
{
if (activeState != null)
activeState.StateUpdate();
}
void OnGUI()
{
if (activeState != null)
activeState.ShowIt ();
}
public void SwitchState(IStateBase newState)
{
activeState = newState;
}
}
But for example here I get the error:
using UnityEngine;
using Assets.Code.Interfaces;
namespace Assets.Code.States
{
public class BeginState : IStateBase
{
private StateManager manager;
public BeginState (StateManager managerRef)
{
manager = managerRef;
Debug.Log ("Constructing BeginState");
Time.timeScale = 0;
}
public void StateUpdate()
{
if (Input.GetKeyUp(KeyCode.Space))
manager.SwitchState(new PlayState (manager));
}
public void ShowIt()
{
if (GUI.Button (new Rect (10, 10, 150, 100), "Press to Play"))
{
Time.timeScale = 1;
manager.SwitchState (new PlayState (manager));
}
}
}
}
And so on with every other script.
I've already installed a newer version of unity3d, uninstalled the antivirus, checked the file names but the error persists. I also do not have any class in a namespace..
Make sure your script file is named exactly as the MonoBehaviour class it contains.
MyScript.cs:
using UnityEngine;
public class MyScript : MonoBehaviour
{
}
Also, if your script file contains helper classes, make sure they are placed on the bottom of the file, never on top of the MonoBehaviour subclass.
Also, Unity will sometimes have problems when your MonoBehaviour classes are in namespaces. I don't know when exactly this happens, it simply does every now and then. Taking the class out of a namespace fixes the error.
I had a strange variation of this issue, and did not see the solution posted anywhere else online.
TLDR
I had whitespace in the namespace for the classes which Unity could not identify as MonoBehaviours.
Background
I had the No MonoBehaviour scripts in the file or ... warning text on two script files in my project, one a MonoBehaviour, and the other a ScriptableObject. Each issue had different symptoms:
MonoBehaviour
The MonoBehaviour class was named like MyMonoBehaviourService.
The script file was named MyMonoBehaviourService.cs
The class was not partial, it had no nested types, nor any other types defined within the file.
I could not attach MyMonoBehaviourService to a GameObject via the inspector, but I could via gameObject.AddComopnents<MyMonoBehaviourService>(). This resulted in the script attached to the object, looking and behaving correctly.
Upon entering PlayMode, I would get the error: The referenced script (Unknown) on this Behaviour is missing!
After exiting PlayMode, the GameObject with the MyMonoBehaviourService attached would now say that it was missing.
Scriptable Object
The ScriptableObject class was named like MyScriptableServiceData.
The script file was named MyScriptableServiceData.cs.
The class was not partial, it had no nested types, nor any other types defined within the file.
I was able to create a MyScriptableServiceData via C# and save it using the AssetDatabase.
I was then able to see and modify the properties using the inspector.
Upon exiting and re-opening the project, the asset would say that its script was missing.
Resolution
Strangely enough, the issue was actually whitespace in the namespace for each class. I mistakenly thought I was seeing word-wrapping but actually, there was a newline in the namespace.
namespace Appalachia.Prototype.KOC.Areas.DeveloperInterface.V01.Features.PerformanceProfiling.Services.
FPS
{
public sealed class FPSProfilerService : MonoBehaviour
{
}
}
needed to be changed to this:
namespace Appalachia.Prototype.KOC.Areas.DeveloperInterface.V01.Features.PerformanceProfiling.Services.FPS
{
public sealed class FPSProfilerService : MonoBehaviour
{
}
}
I'm not sure why this causes an issue with MonoBehaviour/ScriptableObject detection but it really took a while for me to uncover.

In C# are the `using` directives of the base class inherited by the child class?

Let's say we have a base class Rectangle and a derived class Square:
namespace Shapes {
using System.Foo;
public class Rectangle {
public Rectangle(int l, int w){}
}
}
namespace Shapes {
public class Square : Rectangle
public Square(int l, int w){}
}
Does the Square class have to explicitly say that it is using System.Foo? I'm getting erratic results. In one project the using directives seem to be inherited and in a web application they aren't.
using statements, in this context, don't compile to code -- they are helpers to make your code read cleaner for others. As a result, they are not "inherited".
So, to answer your question, your Square class needs to reference System.Foo - either with a using statement, or by using a fully qualified class name.
A using statement will only propagate to the next set of closing braces (}) from the level it was declared on within the same the file.
//From File1.cs
using System.Baz;
namespace Example
{
using System.Foo;
//The using statement for Foo and Baz will be in effect here.
partial class Bar
{
//The using statement for Foo and Baz will be in effect here.
}
}
namespace Example
{
//The using statement for Baz will be in effect here but Foo will not.
partial class Bar
{
//The using statement for Baz will be in effect here but Foo will not.
}
}
//From File2.cs
namespace Example
{
//The using statement for Foo and Baz will NOT be in effect here.
partial class Bar
{
//The using statement for Foo and Baz will NOT be in effect here.
}
}
using directives are only shared if the classes are in the same file and they are not nested in the classes themselves like in your example.
For instance:
using System.Foo;
namespace N
{
class A {}
class B {}
}
If this is all in one file, A and B can both use Foo.
I think everyone is missing the point when it comes to using directives. They really have nothing to do with the class at all. using directives in a code file (.cs, .vb, etc...) are not part of the classes defined within the file. They are used by the compiler to resolve namespaces when compiling.
using System.Foo;
namespace Shapes {...
Importing should always be top most and not within a namespace. This will allow the entire structure of the class to rely on that import when needed.

Namespace vs Class Declaration

I'm new to C# and I can't seem to find any info on this so I will ask it here.
Do classes in namespaces have to ever be declared?
using System;
public class myprogram
{
void main()
{
// The console class does not have to be declared?
Console.WriteLine("Hello World");
}
}
If I'm not using a namespace then I have to declare a class
class mathstuff
{
private int numberone = 2;
private int numbertwo = 3;
public int addhere()
{
return numberone + numbertwo;
}
using System;
public class myprogram
{
void main()
{
// the class here needs to be declared.
mathstuff mymath = new mathstuff();
Console.WriteLine(mymath.addhere());
}
}
Am I understanding this correctly?
A namespace is simply a way to make clear in which context the class is living in. Think of your own name, Ralph. We have many Ralphs in this world, but one of that is you. An extra way to get rid of the ambiguity is to add your surname. So that if we have 2 Ralphs, we have a bigger chance of talking about you.
The same works for classes. If you define class AClass and you would have the need of define another class AClass there would be no way to distinguish between the two. A namespace would be that 'surname'. A way of having to classes, but still able to distinguish between the two different classes, with the same name.
To answer your question, it has nothing to do with "not having to declare". It would only be easier to write code.
For example:
using System;
public class myprogram
{
void main()
{
// the class here needs to be declared.
Console.WriteLine("blah");
}
}
Because of the using System; you don't have to declare the namespace of Console. There is only one Console available, which lives in the System namespace. If you wouldn't declare your using System; namespace then you'd need to explain where Console can be found. Like this.
System.Console.WriteLine("blah");
From MSDN:
The namespace keyword is used to declare a scope. This namespace scope lets you organize code and gives you a way to create globally unique types.
For more info check MSDN for namespace.
I think what you mean is "can you declare a class without a namespace?". Yes you can, it's referred to as the global namespace.
class BaseClass
{
}
class SubClass : global::BaseClass
{
}
However, this is very bad practice, and you should never do this in a production application.

Namespace-only class visibility in C#/.NET?

In C#, can you make a class visible only within its own namespace without living in a different assembly? This seems useful for typical helper classes that shouldn't be used elsewhere.
(i.e. what Java calls package-private classes)
You can make the classes internal but this only prevents anyone outside of the assembly from using the class. But you still have to make a separate assembly for each namespace that you want to do this with. I'm assuming that is why you wouldn't want to do it.
Getting the C# Compiler to Enforce Namespace Visibility
There is an article here (Namespace visibility in C#) that shows a method of using partial classes as a form of "fake namespace" that you might find helpful.
The author points out that this doesn't work perfectly and he discusses the shortcomings. The main problem is that C# designers designed C# not to work this way. This deviates heavily from expected coding practices in C#/.NET, which is one of the .NET Frameworks greatest advantages.
It's a neat trickā€¦ now don't do it.
I don't think that what you want is possible.
internal is assembly (strictly speaking module) privacy. It has no effect on namespace visibility.
The only way to achieve privacy of a class from other classes within the same assembly is for a class to be an inner class.
At this point if the class is private it is invisible to anything not in that class or the outer class itself.
If protected it is visible to everyone that could see it when private but is also visible to sub classes of the outer class.
public class Outer
{
private class Hidden { public Hidden() {} }
protected class Shady { public Shady() {} }
public class Promiscuous { public Promiscuous() {} }
}
public class Sub : Outer
{
public Sub():base()
{
var h = new Hidden(); // illegal, will not compile
var s = new Shady(); // legal
var p = new Promiscuous(); // legal
}
}
public class Outsider
{
public Outsider()
{
var h = new Outer.Hidden(); // illegal, will not compile
var s = new Outer.Shady() // illegal, will not compile
var p = new Outer.Promiscuous(); // legal
}
}
In essence the only way to achieve what you desire is to use the outer class as a form of namespace and restrict within that class.
No, it is possible. You can use internal class in another assembly.
For example I have a internal string extension class that located in SharMillSoft.Core assembly, if I want use it in another assembly that name is SharpMilSoft.Extension, I must use assembly attribute like as below:
using System;
using System.Linq;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("SharpMilSoft.Extensions")]
namespace SharpMilSoft.Core.Extensions.Strings.Public
{
internal static class SharpStringExtensions
{
public static bool IsNullOrEmpty(this string data)
{
return string.IsNullOrEmpty(data);
}
}
}
And I use this class in SharpMilSoft.Extension assembly like as below:
namespace SharpMilSoft.Extensions.Strings
{
public static class SharpStringExtensions
{
public static bool IsNullOrEmpty(this string data)
{
return Core.Extensions.Strings.Public.SharpStringExtensions.IsNullOrEmpty(data);
}
}
}
Note: Then SharpMilSoft.Extensions assembly will be friend assembly for SharpMilSoft.Core assembly
For more details about friend assembly, you can visit this link : Friend assemblies
If you have a single assembly you can define as many namespaces in that assembly as you want but no matter what modifier you apply in the IDE you will always be able to see the classes in other namespaces.
Not sure if it is directly possible, but a few good ways to fake it would be:
1) Have the classes that need this sort of stuff inherit from a single class which has the helper class as an internal class.
2) Use extension methods and then only reference the extension methods within the namespace.

Categories

Resources