Let's say that my main class is this:
public class mainActivity: MonoBehaviour { ... }
When I want to initialize an Image for example, I have to declare it as:
public Image myImage;
Only then I can have access to this instance from Unity's menu. My question is simple. In OOP when we want to access a variable without creating an object we declare it as static. So it becomes class' variable. Right? But Unity lets me create an Image while it's not static and I don't create an object of my class.
How is this possible? Does unity create any "invisible" object of my main class or so?
It's not necessarily an invisible object. The class in question is serialized into a text-based version of the class in which Unity is able to read/write from the editor. If you open a .Unity scene file in a text editor you will see this serialization in practice.
Related
A little background: I'm new to C# and Unity, but catching on very quickly. I'm also hoping this thread will not spark a debate about the merits of classes and abstract coding, as that debate is unrelated and well-worn (and unnecessarily heated); so please keep that in mind.
I'm simply wondering if every C# script in Unity is required to have a main class in any way or for any reason.
Or instead, can methods, and variables can be written outside of a class in a blank file (with namespaces) to be used in a video game?
I'm asking because, when I create a new C# script, it seems to force a class into my file and I'm afraid of breaking things.
I hope to keep code abstraction to a minimum, and the current project
I'm working on has several situations where a class is not needed, or
only one instance of the class will be used. I'd like to simply avoid
using classes in those cases.
In terms of declaring/defining variables and methods outside of any class, you can't really do that in C#. It just isn't how the language was designed (the answers to the question I linked to expand on that idea, so I won't duplicate them here).
You're not without options, though; if you have a number of variables or methods that need to be accessible from different places and don't need an object reference, you can make them static, so you won't need to instantiate the class to make use of them:
public class UtilityClass
{
public static float GravityConstant = 3.51f;
public static string GameName = "MyFirstGame";
public static float CalculateProduct(float a, float b)
{
return a * b;
}
}
Then, you can reference the class's methods/members by accessing it through its name:
float product = UtilityClass.CalculateProduct(6, 1.5f);
An example of where you might use this pattern is when defining mathematical formulae which aren't included in Unity's Mathf methods, and using them in multiple classes.
Additional note: Creating a new C# script through Unity's editor UI will default to declaring a class of the same name that inherits from Monobehaviour. You can alter it to remove the inheritance from Monobehaviour if you don't need any of the methods/attributes of the class, which avoids unnecessary overhead. One example for this would be with a static class that you never need to instantiate.
Yes, you are.
In C#, things like global variables and functions just do not exist. Everything must be contained in a class.
"But what should I do in order to declare some stuff that can be accessed everywhere, without creating an object?" you asked. There is something called the static modifier. You can access the methods or variables or fields or properties marked with this modifier without creating an object of that class.
You just add the word static in a method and it becomes a static method! How simple!
Let's see an example.
I have this non-static method:
public class MyClass {
public void DoStuff () {
}
}
I can call it like this:
var obj = new MyClass();
obj.DoStuff();
But if I modify it with static,
public class MyClass {
public static void DoStuff () {
}
}
I can call it like this:
MyClass.DoStuff();
How convenient!
Note:
Please do not misuse the static modifier! Only use it when it makes sense! When? When the method is a utility method or when the method does not belong to individual objects but the class itself.
First of All you need to check where Methods define as offical
docs stated
"Methods are declared in a class or struct by specifying the access
level such as public or private...."
So, Method should be declare in a Class or struct and A given class
should be, ideally, responsible for just one task.(see also)
Your this question "Or instead, can methods, and variables can be
written outside of a class in a blank file (with namespaces) to be
used in a video game?" answer is hidden in the below question.
Can there be stand alone functions in C# without a Class?
No. Make them static and put them in a static utility class if they indeed don't fit within any of your existing classes.
You have to make a class in order to use methods or its variable
either instance class or static class.
Am I required to use Classes for every script? Every script means you required a class. Unity Support Component Based
Architectural Design and if you require any script related
work then you definitely require a script component which means a
class require.
Finally for singleton, thanks to Unity3dWiki great detail
available. I think you will be feel comfortable to code and writing
class if you keep in mind component based architecture of Unity3d.
Singleton vs Static: I will also recommend to check this: Why do you use a Singleton class
if a Static class serves the purpose
Hope it will help.
[Note: If this helpful Any one can update this answer for future reference and use].
I am making a game using MonoGame and C#. The main class is called Program.cs and is automatically added when creating the project. It uses these lines of code to run the game:
using (var game = new Game1())
game.Run();
The Game1 class contains properties that I need to use in other classes, but the only way to access them at the moment is by making the properties static and using code like the following:
int exampleNumber = Game1.MyNumberProperty;
I'm sure that this is bad programming practice, so I was wondering if there was any way for me to access the "game" instance variable from Program.cs so that I don't need to use static properties. However, the "game" instance is a local variable. Is there any way at all for me to call it using a manner like the following:
int exampleNumber = Program.game.MyNumberProperty;
Edit:
I've created an example class to hold some of the variables and have instantiated it in the Game1 constructor.
MyClass exampleClass;
public Game1() : base()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
exampleClass = new MyClass(); //The class is instantiated here
}
However, I am confused as to how I can now access this instance in another class. The way that I am doing it now is to make the instance static and use a static property, but now I'm back to the original problem.
Put your variables inside specific classes, something that describes them better than just game. For example, a Settings class, this way you would actually ask for the Settings object that is stored in the game class, it gives more context to what your dependencies are.
Now, to fix the static property you would have to create for the Settings class, you have 2 ways:
1: Instantiate all objects manually in the start up of the game class, basically you will wire all the dependencies yourself.
2: Use a dependency injection framework like Unity.
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.
Another best practice question. I have a list of ScriptableObjects now (thanks to LearningCocos2d) which defines a list of sprites I can load at runtime.
I followed this tutorial: http://www.jacobpennock.com/Blog/?p=670
In order to drive some custom behaviour, I want different scripts applied to my various in-game objects when I instantiate them. What's the best way to store the references to the desired scripts I want to apply?
[Edit] Some more details:
My scriptable object is a simple list of serializable objects. I have a series of defined scripts that I want to attach to the objects I define. Unity however does not seem to allow me to store a reference to the script using the below method.
public class TestList : ScriptableObject {
public List<MotionSpriteData> MotionSprites;
}
[System.Serializable]
public class MotionSpriteData {
public Component motionPath;
}
Create a class that loads all the scripts into an array. This class does not necessarily have to be a MonoBehaviour, but for this example it will be.
You have two options:
Drag and drop the scripts into the array via the Editor.
Or put all the scripts in the Resources/Scripts/ folder so that they can be loaded at run time.
public class ScriptManager : MonoBehaviour
{
public Object [] list;
void Awake()
{
// Comment this line if you used step 1 above.
list = Resources.LoadAll("Scripts");
gameObject.AddComponent(list[0].name);
}
}
Now you can use your own logic to determine which GameObject gets which Script, but that should be trivially easy for you.
Just coming back to this question, since my original answer is actually incorrect as someone pointed out. Monoscript stores references to individual scripts (strongly typed), but Monoscript is only valid in the UnityEditor namespace.
Since my question is about best practice, I offer what I have done as a proposal, but since I'm still only 2 months into Unity dev, I'm interested in other opinions. What I ended up doing is building prefabs for each object type, which leverages the power of the Unity WYSIWYG interface. Thus, storing references to scripts becomes irrelevant, since the prefab contains all the behaviours I need.
Since I still need a data layer for my game to drive the game play, my scriptable objects have hence become simpler. The problem of referencing the script becomes instead the problem of referencing the prefab which contains the scripts.
FunctionR has described in his answer how you can use Resources.Load to load content at runtime. However, my question is about how to reference the individual script I want. What I have done is simply store a path to the resource (ie: prefab) I want loaded, as a string.
Unity script assets are of type "MonoScript". Simply declare a variable as this type and it will work.
http://docs.unity3d.com/ScriptReference/MonoScript.html
I have a bunch of screens that all inherit from a base abstract class called GameScreen. They include various buttons that, if pressed, I want to use to change the Current Screen. For now, I am trying to change the screen from startScreen to overviewScreen.
I have a variable in my Game1 class:
public GameScreen CurrentScreen;
Which is initially set as:
CurrentScreen = startScreen;
I then use the following lines to Update and Draw the game, based on which screen is the Current screen:
CurrentScreen.Update();
...
CurrentScreen.Draw(spriteBatch);
In my startScreen classs, I want to write something like this within the update method:
if (//Button is pressed)
{
game.CurrentScreen = overviewScreen;
}
Now clearly that won't work. But I can't see how to do it. Basically I want to access the CurrentScreen variable from within a class, and change it to whichever screen I want, and I feel like there must be a clean way to do this.
Let me know if any additional info is required, I feel like I haven't explained this at all well.
EDIT
startScreen and overviewScreen are classes that, primarily contain the Update and Draw methods for screens I want to display. GameScreen is a base class they all derive from. CurrentScreen is just meant to be a variable that determines which screen is active.
Ok, notw it's cleaner for me. You could add few methods to your Game1 class
public void SwitchToStartScreen(){...}
public void SwitchToOverviewScreen(){...}
//etc
Then you could add a property to your startScreen class (and other ones too)
public Game1 Parent {get;set;}
And force the constructor to pass Game1 object, in which you would assign that parameter to Parent property. Then on particular condition you could just use
Parent.SwitchToOverviewScreen();
Accessing and changing properties manually from outer classes is violating object-oriented principles.
Also, use brief naming convention, because it's hard to understand what you wrote if one of class definitions uses Pascal case while other use Camel case. Your startScreen has more like an object name, while it's used like a class name. Eithar that or you're not seeing the difference between class and an object.
By default in C# Pascal case is used for declaring classes.
use the static objects
public static GameScreen CurrentScreen;
and same for the overviewScreen