What is MonoBehaviour in Unity 3D? - c#

using UnityEngine;
using System.Collections;
public class VariablesAndFunctions : MonoBehaviour
{
int myInt = 5;
}
The full code is here Unity Official Tutorials
What is the purpose of MonoBehaviour

MonoBehaviour is the base class from which every Unity script derives. It offers some life cycle functions that are easier for you to develop your app and game.
A picture is worthy of thousands of words.
Source of the image: https://docs.unity3d.com/uploads/Main/monobehaviour_flowchart.svg

While the following statement is correct,
"MonoBehaviour is the base class from which every Unity script derives" -
I honestly feel it can be misleading to beginners. The phrase - "every Unity script" - being the culprit.
It gives a beginner the notion that all scripts created in unity must extend Monobehaviour. Which is not the case. You can create scripts that house classes that extend the c# base object class. In doing so, your script is then categorised as not a Unity script but nothing stops it from interacting with other Unity scripts and vice versa.

MonoBehaviour is another class that VariablesAndFunctions is inheriting from. This allows the inheritor to use the methods and variables of the other class providing they have the correct access level modifier set.
In the below example Class1 inherits from Base and so can use the protected method Method1
public class Base
{
protected void Method1 { /*...*/ }
}
public class Class1 : Base
{
public void Method2 { Method1(); }
}
Note in this particular example it would be better for Method1 to be marked as abstract or virtual so then Class1 can override it like so:
protected override Method1()
{
//...
base.Method1(); //Call the implementation of Method1 in Base here
//...
}
In particular though MonoBehaviour is described as being:
MonoBehaviour is the base class from which every Unity script derives.
Therefore when doing scripting in unity, you use this base class to better control how things are accessed so you do not need to do it yourself.

Monobehavior is what most of your scripts inherit from,
if you go to the documentation Click here!
you will see a bunch of variables and methods you get from this Inheritance.
such as:
Public Methods
Messages
Properties
Public Methods
Static methods
The most commonly used method (its under message in the documentation but honestly its better to see it as a function) is Update , its the main game loop, the speed at which the update function is called is based on your fps. But the important thing to take away is that if you didn't inherit from monobehavior, you wouldn't have access to this game loop.
Another important function that you get from Monobehavior is Start, which is called once on a script, and it's called after awake, so if you want to set some variables up you can do it here.
The important thing to take is that if you made a simple C# class that inherits from nothing, you wouldn't have access to these methods discussed. Monobehavior gives you access to many functions that help you build your game.
There are other behaviors your scripts can inherit from like ScriptableObject and StateMachineBehaviour, which give you access to other methods, but Monobehavior is the most common behavior your scripts will inherit from.
It's also good to note that whenever you use Monobehavior, it comes with a transform, some other scripts (Scriptable objects) don't come with a transform. The transform is simply a position in your game/scene where the gameobject lies its an x,y,z coordinate with rotation and scale.

Related

Is there a way to find first component of type?

Ok so basically I have a script which highlights gameobjects with a specific tag if your mouse is pointing at.
After it's highlighted you need to press a specific key and you will execute a public function inside the interactable object. Now the problem is when I want to search a specific component instead of using it's name, any help is expected. :)
Script isn't a type, but Component is the base type for anything that can be attached to a game object (hence GetComponent having the name it does). Components include things like Transform, MeshFilter, etc. Most scripts that you'll write inherit MonoBehaviour, so you totally could do something like GetComponent<MonoBehaviour>() but then you'll get the one (or all, if you use GetComponents) of the MonoBehaviour scripts attached to the game object.
Since you're just blindly getting any script without knowing its type in advance, you're going to wind up with some big if/else chain where you keep trying to downcast the object to a concrete type that you can actually do something with.
The solution is to use an interface. If multiple classes can all do the same thing, then make an interface that encapsulates that functionality. In your case you might have an IUseKeystrokes interface for all the kinds of classes you could make that would use your keystroke sequence technique.
public interface IUseKeystrokes
{
void Use(char keystroke);
}
Then you add that to any class you're writing and you'll get a compile error if you don't implement the Use(char) method.
public class MyThing : MonoBehaviour, IUseKeystrokes
{
public void Use(char keystroke);
// and other stuff for the class
}
and now finally you can call
IUseKeystrokes useKeystrokes = targetGameObject.GetComponent<IUseKeystrokes>();
and now it actually doesn't matter what class it is, no need to downcast, you just call
useKeystrokes.Use(keystroke);

Polymorphism in Unity with mono-behaviour

I have a problem with polymorphism in unity. I want to create a abstract base "Gun" class to represent guns in my doom-clone game. Next i want to create some children classes like "shotgun","pistol" and so on then make for example list of "Guns" when i store each children. But when i want to do this i need to derive from my base "Gun" class, and not from mono behaviour. That way i cannot store references to for example animator, or audio Source in my children scripts like Shotgun. I want the sound of shotgun to be stored inside shotgun script, so when i want to play it i just call specific object method. But without mono behaviour it seems impossible. I don't think scriptable objects solve my problem either. What should i do then?
Just have
public abstract class Gun : MonoBehaviour
{
// common members like e.g.
// either private -> only this class has access
// or protected -> only this class and inherited classes have accss
// or public -> every other type has access
[SerializeField] protected AudioSource audio;
[SerializeField] protected Animator animator;
// abstract methods all inheritors HAVE TO implement
// maybe virtual methods inheritors CAN overrule or extend but don't have to
// other common private/protected/public methods etc
public virtual void Shoot()
{
// reduce one bullet
// play your sound file etc
}
}
and then each in its own file
public class Pistol : Gun
{
}
and
public class Shutgun : Gun
{
}

Does not implement interface member StartActivityInAndroid

I am trying to open an activity in MainPage through dependency and have the following error:
Can you help me? Thanks
A C# interface is basically a contract - if your class implements an interface, you are saying that you will do all the things the interface requires.
In this case, your class is implementing INativePages which defines a method StartActivityAndroid. So your class must provide an implementation of that method signature.
If you click on the "show potential fixes" link VS will automatically create a method stub for you.
Let's take an example. Say that I am a Robot and I can shoot people all around around me. But, the issue is I don't have a gun. I also don't understand how a gun works. But I know that a gun is an object which has a trigger which when pressed kills people. So, the code for this will look something like below:-
public class Robot{
public void ShootPeopleWith( weapon IWeapon ){
weapon.PressTrigger()
}
}
interface IWeapon{
PressTrigger()
}
You see the Robot expects anyone who wants it to shoot people to provide him with a weapon first. Now, he doesn't know what weapon. Whatever you provide me, it should have a trigger because I only know to press the trigger and I know it serves my purpose. If you provide me with something that doesn't have a trigger, I cannot function.
Now, there comes a drone that instructs the Robot to shoot people. It also provides it with a gun.
public class Drone{
List<Robots> allRobotsInArea = someList
public void DelegateARobot(){
robot = select a robot from allRobotsInArea
IWeapon weapon = new MachineGun(); //procuring a machine gun
robot.ShootPeopleWith(weapon);
}
}
You can see here that IWeapon is an agreement between the Robot and Drone. It says that whatever you give me must have a trigger. So, machine gun must have a trigger. Let's implement few weapons:-
public class MachineGun : IWeapon{
public void PressTrigger(){
Fire40RoundsPerSecond();
}
...
}
public class Sniper() : IWeapon{
public void PressTrigger(){
SayQuackQauck();
}
}
The Drone can now easily pass in any weapon like Sniper and MachineGun to the Robot.
public class Pumpkin{
public void FreakPeopleOut(){
GlowInTheDark();
}
}
The drone cannot pass in a Pumpkin even though it can be used as a weapon as robot.ShootPeopleWith(new Pumpkin()); because it doesn't have a trigger and breaches the contract that Robot expects.
In your case, the Android Operating System is possibly the Robot in the above story which expects anything of type INativePages so when it consumes your NativePages object, it will try to call StartActivityInAndroid(). It doesn't know the activity or how to start it, so you must specify it in the method. Pressing Alt + Enter in Windows will auto-generate this method for you. You will have to then write logic on how to Start the Activity in Android.

Finding and starting a generic class?

I have a Unity C# application where every game inside has one abstract controller. It inherits from another class enabling it to be accessed like a static version of the base behavior in unity.
public class AbstractController<T> : SingletonMonoBehavior<T> {
virtual public void Begin() {
//startup code here
}
}
So, to find this class, I have to know what T will be. Do I need reflection for this? Or can I just store T types in a List somewhere, and access them dynamically? Right now, I DO have a dictionary of game names and classes that inherit from abstract controllers -- so I know what T is supposed to be, but when I do this:
_controllerTypes = new Dictionary<GameScene, Type> ();
_controllerTypes.Add (GameScene.FrogJump, typeof(FJGameController));
Type T = _controllerTypes [_startScene];
AbstractController<T>[] controllers = GameObject.FindObjectsOfType<AbstractController<T>> ();
I get a compiler error stating that "The type or namespace name `T' could not be found." Is there a way to design around this? I don't want to use reflection, but I want it to be pretty.
What you are about to do is absolutely possible but requires the use of reflection. You shouldn't do this as it will affect the performance of your game. Like Catlard mentioned in the comment section, use interface.
interfaces allow you to guarantee that a class has a function, but how
do you access that class in the first place? You can't just
GetComponent for all IControllable interfaces, for example. I'd still
have to have an abstract controller class, right?
You can use GetComponent to check for an interface.
public class Player : MonoBehaviour, IControllable
{
}
then your Interface:
public interface IControllable
{
}
Now, lets say that your Player script is attached to a GameObject called "Player".
GameObject plyrObj = GameObject.Find("Player");
if (plyrObj.GetComponent<IControllable>() != null)
{
Debug.Log("Player is Controllable");
}
Your can also have multiple interface for different classes. You can also make the interface generic with something like public interface IControllable<T>{}. This should help you re-do your work.

Declare a variable class

i need to declare a variable class in my code so i can access a function (having the same name in all classes) but doing each time a different behavior).
and this is my code:
using UnityEngine;
using System;
using System.Collections;
public class Bubble : ItemBehaviour
{
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
}
void OnMouseDown ()
{
theclass.Behaviour ();
}
}
knowing that (theclass gonna be variable ).
Thank you guys for your answer but it is a bit special.
My game is about interaction between player and game objects when the player approach any item that is "interactible" lets say, a bubble shows up, this bubble is a GameObject and it is the same for any object that allow interactions,
So since i am doing a 2D game i thought, it would be great if i make a "universal"
EmptyGameObject that contains all common aspects that anyObject would contain, and i grouped main functions and common ones in a general script and i added it to this emptyGameObject, then i added the Bubble prefab to this Game object and i a dded a code to it this code contains what i wrote in my firs post.
i was thinking that now each time i want an object i just drop this emptygameobject prefab and changes sprites and characteristics.
And each object have a different behavior (ex: i can delete an apple as if the character consumed it but i can not consume a door, the door would rather trigger an animation than being destructed ) i am specifying all this in a class for each item.
now whatever the class is (the object is) the trigger is in the bubble class (which i posted first) but the class will be different each time and i can not make a class that contains polymorphism because its not the same context each time.
I think you should create an interface that declares all the functions you would like to use in different classes.
interface IBehaviour
{
void Behaviour();
void AnotherBehaviour();
}
with this you define a behaviour what a class, which implements the interface, is capable of.
And then your classes would be:
class MyClass1 : Ibehaviour
{
}
class MyClass2 : IBehaviour
{
}
Apart from this you can use abstract classes. There are a lot of well-written articles about these topics on the Internet.
Firstly, I recommend to get familiar with OOP principles.
This link is a good way to start.
Good luck.
Thank you all,
The matter was solved by creating a global (abstract) gameOject that contains the class that we want to inherit from, and then each time the gameObject atached to this class calls (Behavior function) it trigger whatever the override is for this function for this object.

Categories