Two stupid questions about calling a method from another script (C#)
I have two scripts.
LevelGeneration.cs:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class LevelGeneration : MonoBehaviour {
//variables here
public void CreateWorld() {
//code for generating level
}
}
And GameManager.cs:
public class GameManager : MonoBehaviour {
void Start() {
}
}
Two questions:
I want to call CreateWorld() from GameManager, but when I tried to do smth like LevelGeneration lvlGen; and in start() lvlGen.CreateWorld() it didn't work - nothing happened. Only an error about instance of an object...
The main thing I'm trying to achieve here is the code organization. So, When I do thing i described above - do I have to repeat all the variables from LevelGeneration in the GameManager..?
And ideally I'd like to put only GameManager.cs onthe gameobject, and leave all other scripts laying in the folder - am I on the right track?
Answer by dkjunior · Oct 16, 2015 at 08:11 PM
Yes, you can have only GameManager to be on a gameobject. Just remove the MonoBehaviour inheritance from the LevelGeneration class definition. It is, of course, depends on what functionality you want to have there, as by doing this you will lose access to what MonoBehaviour provides (such as ability to start coroutines, etc.).
If you go this route, you can then do the following in your GameManager object:
public class GameManager : MonoBehaviour {
void Start() {
LevelGeneration levelGeneration = new LevelGeneration();
levelGeneration.CreateWorld();
}
}
It's very likely LevelGeneration class will need some information from the GameManager about what exactly to create, where to put it in the scene, etc. If you can provide more details/specifics on how you want this to behave, I may be able to suggest other ways to organize the code.
Yeah, that's kinda the problem. Forgot to mention. I use Instantiate, and it inherits from $$anonymous$$onobehaviour... I atached a pic with a sample of the code I'm using right now. As well as variables I use. I guess there's no way to do this code division with LevelGenerator, but I guess I can go the same way with other scripts, as long as they don't need monobehavior. Just curious if I gotta devlare variables in the target script and then just get them in Game$$anonymous$$anager, like, testVar = lvlGen.testvar or smth.
For completeness' sake, you can also use GameObject.Instantiate static method to create objects outside of $$anonymous$$onoBehaviour. But in your case it's probably better to stick with $$anonymous$$onoBehaviour as it seems you are using some of the other functionality it provides, such as ability to assign variables from the inspector.
You can attach both Game$$anonymous$$anager and LevelGeneration to the same gameobject if you don't want too many "manager holder" empty gameobjects in your scene.
Now, back to the second part of your question - how to call LevelGeneration from Game$$anonymous$$anager. $$anonymous$$ultiple ways to do that, three most common:
Create a reference to LevelGeneration inside Game$$anonymous$$anager object:
public LevelGeneration levelGeneration;
And then drag-and-drop LevelGeneration gameobject into it in the inspector.
If both Game$$anonymous$$anager and LevelGeneration are attached to the same gameobject, you can access it through GetComponent:
public class Game$$anonymous$$anager : $$anonymous$$onoBehaviour { public void Start() { LevelGeneration levelGeneration = GetComponent<LevelGeneration>(); levelGeneration.CreateWorld(); } }
If Game$$anonymous$$anager and LevelGeneration sit on different gameobjects, you can find it using Find:
public class Game$$anonymous$$anager : $$anonymous$$onoBehaviour { void Start() { LevelGeneration levelGeneration = FindObjectOfType<LevelGeneration>(); levelGeneration.CreateWorld(); } }
Answer by $$anonymous$$ · Oct 16, 2015 at 08:16 PM
There are two methods to do this: First method is the Unity way, the proper one to use in most situations.
In your GameManager script you instantiate an instance of LevelGeneration MonoBehaviour. You have to attach both scripts on the same gameObjects tho (or you can put it on another gameObject then read that gameObject into the variable and then do the same). This is done like this:
public class GameManager : MonoBehaviour {
private LevelGeneration levelGen;
void Start() {
levelGen = getComponent<LevelGeneration>();
levelGen.CreateWorld();
}
}
Second method is to make CreateWorld method as a static public method. This fits your need more, tho you have to make every method and the script static too. This is a little less memory efficient especially when you're working with a lot of variables.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public static class LevelGeneration {
//variables here
public static void CreateWorld() {
//code for generating level
}
}
then you can call it from GameManager as LevelGeneration.CreateWorld();
public class GameManager : MonoBehaviour {
void Start() {
LevelGeneration.CreateWorld();
}
}
Do I understand it right if I declare method as static, then I can't change variables thorughout the game? I mean, I don't need it in LevelGen, but when I implement battles, the HP and so on will change
Anyway, it gives me an error:
Assets/Scripts/LevelGeneration.cs(5,21): error CS0713: Static class
LevelGeneration' cannot derive from type
UnityEngine.$$anonymous$$onoBehaviour'. Static classes must derive from object
I have to edit my answer. I forgot to mention that your script can't derive from $$anonymous$$onoBehaviour ! And to your question, static means it will stay in the memory untill the program is running. So you can change it anytime :)
Your answer
Follow this Question
Related Questions
Detect if UI Button is pressed 0 Answers
Settings menu of main menu not updating in settings menu of pause menu. Unity C#, 0 Answers
How can i run a script with a single key press? 1 Answer
Having transitions between two VideoPlayers triggered by clicking "x" times in a text layer 0 Answers
How to add a editing option to variables in a script in Inspector? 0 Answers