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
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.
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.
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”.
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!”