can't attach script: "script needs to derive from MonoBehaviour"

Hello

I have a global script (js) “MyGlobals” that contains a couple of classes which record scores on each level of the game, and another that I use to track a bunch of stuff. There are a bunch of static functions too, which I use in various other scripts. Long and short, these items are used everywhere.

Now I need to have that script attached to an object, (so that I can attach the EZGameDataSaver script, which will then read/save them.)

So I created a new empty object and dragged the MyGlobals script to it… only to get “Can’t add script behaviour MyGlobals. The script needs to derive from MonoBehaviour!” I searched around for several hours trying to figure this out, to no avail. Is there something bone-headed ignorant I’m missing? (Well, of course there is, or I wouldn’t have this problem.

Just in case it helps, (dramatically abbreviated to save bandwidth, but still show the structure) “MyGlobals.js” is:

import System;
import System.Text.Encoding;


class LevelScoreClass {
   var level : int = 0;
   static   var badWords : int = 0;

//snip
}

class MyGlobals
{
    static   var word: String = "";
    static   var wordArray = new Array();
// snip   
}

// massive snip of a bunch of static functions here to save bandwidth


static
function myDebug(s1 : String, val: String) {

    var xx: String;
    xx += s1 + "  " + val;
    Debug.Log(xx);
}

static 
function initScores(){
   
//snip

}

// etc

Highlighting the script shows [mono] as the type.

Hints or help greatly welcomed :expressionless:

I’ve managed to get it working by changing

class MyGlobals

to

class MyGlobals_c

It appears Unity doesn’t like having the class with the same name as the script. Not 100% sure why though!

The name of the script is the name of the class. You just don’t need to be explicit about it because Unity handles it with JS. Your script is not designed quite right; you need to think about it in those terms. Having a class called MyGlobals, with another class called MyGlobals contained within, doesn’t make sense.

Also, if you explicitly declare the class, like in C#, which you are doing here, unintentionally, you need to put “extends MonoBehaviour” after the name of the class, or else it won’t be a MonoBehaviour.

I don’t know what’s actually going on behind the scenes with the rest of the script, but it’s not really important to find out, because you shouldn’t be doing it. One class per script, that matches the file name. Classes defined within these scripts cannot be named the same as the enclosing class.

Thanks, NK, but changing the filename or t he class name toasts everything, even within the .js file itself.

Jessy… AHA! (I’m a traditional programmer (C, C++ etc) w here the file names are not related that way. Never occurred to me. So to test, I just went in and commented out my class definition, and the program still runs just fine… AND… I can drop the file on to my object.

I thought it had to be something fundamental, and you’ve helped me overcome a huge misunderstanding about how Unity works. I’m going to have to go back and look at a bunch of stuff now, just to be safe.

Thanks so much, Jessy. Problem solved.

Awesome. You’ve helped me understand some important fundamentals before, too, so I’m glad to return the favor! If you do figure out what happens to code outside of the class/script definition (I think you’re better-equipped to find out than I am at present, with your background), please post it here. I’m just interested in knowing how things work, even if you’re not using them “right”. :slight_smile:

I’m not sure where it’s documented, but Unity uses the name of the .js/.cs file as the name of the class to instantiate when you add it as a component to the game object.
If your source file was C#, then you’d never be able to use it at all by doing what you did - ie: class Mumble_c in the file Mumble.cs - Unity would complain and not work.
For your global-score class thing, you don’t need to attach to a game object directly, but you do need to reference it. Add a class variable to some class that is going to be accessing your globals, and then drop your global class .js file into that slot. You’ll probably need a singleton pattern for this.

Thanks, nopcode. In view of what I just learned, that makes perfect sense. I appreciate all the education I’m getting: it just shortens the time between “this is weird and hard” and “this is fun!” :slight_smile:

Make’s perfect sense when you say it like that! I guess i’ve learned something too as well, thanks :slight_smile:

Ran into this too, and it doesn’t appear to be mentioned, but it’s case sensitive too. :slight_smile:

Meaning Class MyClass , with a script filename of myClass.cs will flag up this error and not compile.

class MyGlobals - Monobehavior
hope this helped