- Home /
Not properly understanding how monobehaviour scripts act without a GameObject.
I have three files(scripts), which each contain a class of the script name. Account, Player(MonoBehaviour) and GameManager (MonoBehaviour).
Account is essentially a save slot. It holds a users gold, status in the game, and most importantly a list of players ( public Player[] team ).
Player holds the attributes that a player(character) should have (hp, attack power...). These variables need to exist even when the game is not actively being played.
GameManager is what creates and allows the game to be played. It contains a list of gameObjects that will physically represent the player.
I was told previously to make my player and Account scripts not inherit from MonoBehaviour, but this means my gameObjects won't have the player script attached to them, which makes interactions funky.
So I decided to make Player a monobehaviour script, but if I do this I have trouble keeping scripts without a GameObject.
My questions are : Can I have a script without a GameObject? If not, should I make team(within account) a GameObject array that stores the players? If not, what is the best way to implement this?
public class Account{
private string accountName;
public int gold;
public int teamSize = 15;
public int playerCount = 0;
public Player[] team;
//public GameObject[] team;
public Account(string newAccountName){
accountName = newAccountName;
gold = 10;
team[0].newPlayer("Garet", "Mage", 0);
team[1].newPlayer("Karla", "Ranger", 0);
team[2].newPlayer("Tyler", "Warrior", 0);
playerCount = 3;
}
}
public class Player : MonoBehaviour{
public string playerName;
public string className;
public int experience;
public int health... etc....
//constructs a new player
public void newPlayer(string newCharName, string newCharClass, int newExperience)
{
playerName = newCharName;
className = newCharClass;
experience = newExperience;
setStats();
}
}
public class GameManager : MonoBehaviour {
//other scripts
public Player player;
public Account currentAccount;
//Stores the gameObjects
List<GameObject> playerModels = new List<GameObject>();
//Awake is the first thing called, and instantiates all scripts
void Awake()
{
currentAccount = new Account("tempAccount");
}
//Start is called just after Awake, and instatiates all players and global variables
void Start()
{
//create representations of players
addPlayers(2);
}
//adds numberOfPlayers many plays from account into game.
void addPlayers(int numberOfPlayers)
{
//loop through numberOfPlayers and create gameObjects for them.
for(int i=0; i < numberOfPlayers; i++)
{
//creates a capsule gameObject to represent the player
//playerModels[i] = GameObject.CreatePrimitive(PrimitiveType.Capsule);
playerModels.Add(GameObject.CreatePrimitive(PrimitiveType.Capsule));
//moves the capsule to the start position determined by its number
playerModels[i].transform.position = spawnPosition(i);
//tags the gameObject as a player
playerModels[i].tag = "Player";
//playerModels[i].AddComponent<Player>();
playerModels[i].AddComponent<Player>();
Player tempPlayerScript = playerModels[i].GetComponent<Player>();
tempPlayerScript.copyPlayer(currentAccount.team[i]);
//TODO set player team??
}
}
Answer by Dracorat · Jul 01, 2014 at 12:27 AM
I think you hit the nail on the head in stating you don't understand why they should or should not be inherited from MonoBehavior.
MonoBehavior is itself a class that allows your objects to be attached to objects that Unity is managing so that it can manage them as a special object type of its own.
In short, if you're attaching a class to an object, it should always inherit from MonoBehavior.
However! If you have created a class that is not directly tied to in-game objects (examples might include a class to manage scores, or game-wide settings, or logical classes of data that have no in-game object such as save / load code) then you are adding the overhead of a class by inheriting from MonoBehavior with no added gain.
To put it another way, if your classes directly call the class in question, but do not attempt to attach that class to a Unity Object (actor, etc) then don't inherit from MonoBehavior. If your object violates these, inherit.
If in doubt, you can inherit - you most likely just cost yourself some RAM by doing so.
So my classes do have the proper type then, Account is not monobehaviour, but the other two should be.
Now how should I handle the "$$anonymous$$m" variable within Account?
Should I change it to a bunch of game object that hold a player script? Should I leave it the way it is? If so, I am getting a null reference whenever I try to access the $$anonymous$$m, how do I initialize the scripts?
Team variable: looks fine. Though I'd use a List ins$$anonymous$$d and initialize it in the constructor - but that's a personal style choice and not any more or less "correct".
As for accessing other scripts, there's information I don't have. From what I can tell, it looks like you've attached them to objects in which case you just need to wire them up in the Unity designer.
If you're doing it without $$anonymous$$onoBehavior, you usually just create the class, or if you want to use a singleton, create a singleton pattern or make it static.
Singleton pattern: http://msdn.microsoft.com/en-us/library/ff650316.aspx
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Illuminating a 3D object's edges OnMouseOver (script in c#)? 1 Answer
Awake not called if class has static member 2 Answers
Coroutine without MonoBehaviour 6 Answers