Scripts, Classes and Objects

Wow great I have to redo my entire post because the posting system completely breaks when you try to post without being logged in… consider this my bug report :stuck_out_tongue:

So I’ll make this short…

I’m kind of new to Classes/Objects and I need help understanding them in combination with unity. There is Classes and Objects right? Classes are like the blueprints for Objects, so they dont do ANYTHING unless created as object?

What is the difference between object and instance?

So to my unity based problems.
A script asset is a class? a script component is an object, that is created once the game starts thereby calling its awake and start method for that object?
when you select a script component within the drop down menu on a public class field does it take the instance/object off that script component as a link?

What’s the deal with static fields, are they like constants that you can only set within the class, and have them preset for every object?

Okay tia for any help (or pointing towards a helpful tutorial, really)!
Sorry for asking everything I want to know so directly I’m a little annoyed after what happened last time I tried to post, so I don’t want to paraphrase everything gently.

You are pretty much correct, Classes are blueprints. Classes can also have templates. This is called “extends”. So a class which extends another class takes on the basic principles of the base class (this is called inheritance) You may also overwrite variables and functions within that class. In Unity, we extend the MonoBehaviour class to gain the features of that base class.

Objects are “built” versions of those classes. In Unity, you can use core objects like GameObject to create entities in 3d space. You can also create an object out of a class by use of the word “new”

Objects and Instances are the same thing. Both are objects. In the case of real world programming when you refer to an instance of an object, usually you are refering to the base object. I don’t think this holds true in Unity. Also in Unity, we have things called Prefabs, this could be considered instances or base blocks from which to build by.

It is, or defines one. Also, a script asset is an object for reference in the assets database.

This may or may not be true. In C# you define a extended class from MonoBehaviour, in JS it is implied. The MonoBehaviour class provides you with the Start and Awake functions (and more)

Using anything from the drop down menu has the same effect as dragging it from the Project view to the Hierarchy view or scene. It applies that component to the GameObject. If it is a MonoBehaviour based class, it allows you access to the MonoBehaviour functions and events. Basically, it copies the script to the object so you can use it.

The last question I actually never bothered learning. :smile:

When you create a new C# script you can see the class build as it should be. JS scripts are just blank.

using UnityEngine;
using System.Collections;

public class NewBehaviourScript : MonoBehaviour {

	// Use this for initialization
	void Start () {
		junk myClass = new junk();
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

Observe the class needed to make the Start function work above.

using UnityEngine;
using System.Collections;

public class junk{
	
	void junk(){
		Debug.Log("New Junk Constructed.")
	}
	
	void Start(){
		Debug.Log("This function is not called because we do not extend the MonoBehaviour base class.")
	}
}

Static variables can only have one value across all instances of the class (script) that it’s defined in. I hardly ever use them, unless I have a singleton-esque manager type object that I want accessible from any other script, and even then, its mostly out of the convenience of the fact that you don’t have to cache a reference to the script to access it.

Does this mean that if I change that variable that it changes for all the objects that contain that class?

Ok thanks a lot so far!

That I really struggle with is the question, when do I actually have an object and when is it just a script reference or a class. So far I’ll just add MonoBehaviour to every class that I create. (btw. just a sidenote, are there some deeper differences of C# against JS? Is C# faster?)

If I assume that I create an instance of a class when I add it to a GameObject. And then reference to an actual Instance when I choose the script component for a field. I also assume that when I hit play there is no object whatsoever (none that I coded anway) unless it is attached as script component (being an instance ) or called within another object that was created by attaching it as a script component.

So I cant just have classes in my assets and let them do anything within their Awake method for example.

Till now I find it impossible to find out whether those assumptions are true or false, since It could just me doing something else wrong within my scripts. The compiler just says “nullreference exception for object” or something like that.

Yep.

You actually have an object, when you generate it using the “new” keyword.

This is advisable only for classes that need to use the MonoBehaviour functions and variables. This is not advisable for other objects that do not require such things. (overkill is nice though. In JS everything is assume MonoBehaviour, but is not always so.)

C# and JS are the exact same thing, they compile to the exact same code and use the exact same libraries.

These objects do exist. Classes can be called upon from scripts running in the game environment. The difference is that when you drag a script onto a class it assumes the MonoBehaviour is there and uses it as such. In C# you MUST declare it for it to be so. Once attached to a game object it is actually a Component of that object and can be accessed using the GameObject.GetComponent function.

I am not aware that any Non-Component class uses MonoBehaviour functions. So no, that will not work.

You would have to post some script for us to look at to help with that. :wink:

sry appearently i hit reply instead of quote

How does that normally look like? Don’t you need an object to execute commands like

using UnityEngine;
using System.Collections;

public class Animal : MonoBehaviour
{
void Awake()
  {
    elephant = new animal();
  }
}

In that example how is the Awake method called? There would have to be a object creation first, which will trigger the Awake method to take place, right? Please I’m dying to know, how and when exactly I have objects / instances within unity. Are they created by themselves?

I just know in php you would define a class and it wouldnt do a thing till you create it within the procedural code, even the __Construct function is not called before then.

Is there some writeup to know when you would need MonoBehaviour? Is it just that it can’t be attached and doesnt have stuff like Awake()? So you’d have to call an instance of that class within an object for it to do anything?

Since when do those objects exist? When are they called? How do I reference them?

What I meant is, what if I have a MonoBehaviour class within my assets that is not attached to any GameObject? Will it create an own instance, call Awake method, and whatnot?

Thing is I wanna understand it. I can make my script work without understanding why. So I dont think that will get us any further :slight_smile:

Especially since I wanna start a bigger, more complex, well thoughtout project asap, that would require me to know what exactly unity does, when and why.
In general I use tutorials for that, but they usually just provide you with “create that class with that and then attach it to that object” without ever telling you why, and what exactly is behind all that^^

Objects don’t have an Awake() method, only Monobehaviors do. and Monobehaviors only execute Awake(), Start(), Update(), and all the other workhorse functions when they are attached to a GameObject in the scene, which you would either have to manually create in the editor, or instantiate through script.

Lets play with some code…

This code defines a class… This class wont do a single thing but take up space until we create a new object from it.

public class NewBehaviourScript : MonoBehaviour {
	// NOTE: we are using a monobehavior here because we want the advantage of things starting and updating during the game.
	public junk myClass;

	// Use this for initialization
	void Start () {
		junk myClass = new junk();// create a usable object from the class
		myClass.Start();// forces the object to "Start"
	}
	
	// Update is called once per frame
	void Update () {
		myClass.Update();// forces the object to "Update"
	}
}
using UnityEngine;
using System.Collections;

public class junk{
	
	void junk(){
		Debug.Log("New Junk Constructed.")
	}
	
	public void Start(){
		Debug.Log("This function is not called because we do not extend the MonoBehaviour base class.")
	}
	
	public void Update(){
		
	}
}

Ok, what we do here is to first, create an object in our scene called “Bob” Drag the NewBehaviourScript on top of Bob. That makes the NewBehaviourScript a component of Bob. (very important)

Now, bob starts, he calls on all his scripts to Start which are based off the MonoBehaviour class. So NewBehaviourScript.Start runs. Because it runs, it creates the Object myClass which is NOT based off a MonoBehavior class. Even if it was, because it is not a Component of Bob, it will NOT Start.

We force the Start function in the junk object where we write some debug information.

now, every frame, Bob updates all of its components, which, in this case NewBehaviourScript forces the Update for myClass.

Now, if we drug the junk class to Bob, it would do nothing because it is not based on the MonoBehaviour.

Say we have a different GameObject with a different script, and we want to then “see” Bob, and “see” the NewBehaviourScript script. We have to ask Unity to get it for us.

NewBehaviourScript otherScript = GameObject.Find("Bob").GetComponent<NewBehaviourScript>();

// the JavaScript function works perfect even when calling C# objects.
var other : NewBehaviourScript= GameObject.Find("Bob").GetComponent(NewBehaviourScript);

NOTE: JavaScript is a little less type dependent, so its a little easier on the eyes… for me that is.

You can then access all public components of Bob’s NewBehaviourScript through script. (Including the junk myClass, since it is public.) By virtue, you will also be able to access myClass’s public functions.

A big not e to remember is that Unity… is C#, even if you are in JavaScript. Just because it looks a little different doesn’t make any difference…

System.BitConverter is the same in C# and JS, and you can use it just the same as if you were in C#… And so does (almost) every other .net component

I got to playing with non MonoBehavior classes in another script… in the event there MonoBehavior is Not needed nor wanted.

http://forum.unity3d.com/threads/84571-Timing-when-running-the-game-in-editor-vs-build-is-WAY-off?p=544156&viewfull=1#post544156

So i hope I get this right. If a MonoBehaviour class script is attached to a GameObject as Component it will have its Awake / Start Methods called, and probably the other MonoBehaviour methods too, if they exist. But since its just a class it cant really do anything. The C# code for a class and also the MonoBehaviour is simply saying “hey that is how it looks like and that is what it does”.
So you’d still need an instance to even call methods like “Awake()”. And to me it seems like that instance is created when you attach the class script (if its a MonoBehaviour) to a GameObject (or when you start the game)

I’ve just remembered that I’ve read something like

void Awake()
{
  Instance = this;
}

So it’s probably safe to assume that it creates an object at the very start. Theres just no way to address it since you don’t know it’s name… or do you?

Now please if you understand what I’m saying, tell me if im assuming that right. :slight_smile:

Btw. thanks for the other link, I know now I will have to adjust my DeltaTime workaround at some point…

Edit:
Ok. I’ve just had an error that explained a LOT ^^

You are trying to create a MonoBehaviour using the 'new' keyword.  This is not allowed.  MonoBehaviours can only be added using AddComponent().  Alternatively, your script can inherit from ScriptableObject or no base class at all

So it seems to me the only way to create a MonoBehaviour object is by attaching it to some GameObject

//cheer

those are the basics… :smile:

Yes, MonoBehaviours have alot of methods and variables… check out the documentation

Most of your questions revolved around class creation more than MonoBehaviour anyways… :wink:

No all that I assumed about object creation in general proved to be true.
It’s MonoBehaviour object creation that confuses me.

Normal classes just get called as objects with “new class()” and then they are there. MonoBehaviour objects can only be created as attachments to GameObjects. I don’t even know if you can create them at all within your code, maybe with AddComponent.

Would be great if there was important things like that mentioned within the reference

It could really use a little addition, telling people how exactly you create instances of MonoBehaviour classes.

But maybe thats just me…

There is not much past what is there. MonoBehaviour classes can only be added by AddComponent to an object. Dragging them in the editor does exactly that.

At runtime, you can AddComponent to an object, but it is just the same as if you had drug it there from the editor.

The cool thing is. At runtime, you can pause your game, go into the editor and adjust things. It all works the same in the editor, script or editor at runtime.