Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  4. Build games and experiences that can load instantly and without install. Explore the Project Tiny Preview today!
    Dismiss Notice
  5. Nominations have been announced for this years Unity Awards. Celebrate the wonderful projects made by your peers this year and get voting! Vote here!
    Dismiss Notice
  6. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

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

Discussion in 'Scripting' started by tvalleau, Jun 9, 2011.

  1. tvalleau

    tvalleau

    Joined:
    Jul 1, 2010
    Posts:
    92
    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:

    Code (csharp):
    1.  
    2. import System;
    3. import System.Text.Encoding;
    4.  
    5.  
    6. class LevelScoreClass {
    7.    var level : int = 0;
    8.    static   var badWords : int = 0;
    9.  
    10. //snip
    11. }
    12.  
    13. class MyGlobals
    14. {
    15.     static   var word: String = "";
    16.     static   var wordArray = new Array();
    17. // snip  
    18. }
    19.  
    20. // massive snip of a bunch of static functions here to save bandwidth
    21.  
    22.  
    23. static
    24. function myDebug(s1 : String, val: String) {
    25.  
    26.     var xx: String;
    27.     xx += s1 + "  " + val;
    28.     Debug.Log(xx);
    29. }
    30.  
    31. static
    32. function initScores(){
    33.    
    34. //snip
    35.  
    36. }
    37.  
    38. // etc
    Highlighting the script shows [mono] as the type.

    Hints or help greatly welcomed :-|
     
  2. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,462
    I've managed to get it working by changing
    Code (csharp):
    1. class MyGlobals
    to
    Code (csharp):
    1. class MyGlobals_c
    It appears Unity doesn't like having the class with the same name as the script. Not 100% sure why though!
     
  3. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,327
    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.
     
    Last edited: Jun 9, 2011
  4. tvalleau

    tvalleau

    Joined:
    Jul 1, 2010
    Posts:
    92
    Thanks, NK, but changing the filename or t he class name toasts everything, even within the .js file itself.
     
  5. tvalleau

    tvalleau

    Joined:
    Jul 1, 2010
    Posts:
    92
    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.
     
  6. Jessy

    Jessy

    Joined:
    Jun 7, 2007
    Posts:
    7,327
    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". :)
     
  7. nopcode

    nopcode

    Joined:
    Apr 29, 2011
    Posts:
    60
    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.
     
  8. tvalleau

    tvalleau

    Joined:
    Jul 1, 2010
    Posts:
    92
    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!" :)
     
  9. NomadKing

    NomadKing

    Joined:
    Feb 11, 2010
    Posts:
    1,462
    Make's perfect sense when you say it like that! I guess i've learned something too as well, thanks :)
     
  10. JohnnySix

    JohnnySix

    Joined:
    Nov 9, 2015
    Posts:
    1
    Ran into this too, and it doesn't appear to be mentioned, but it's case sensitive too. :)

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