- Home /
Can a script be used without a gameObject and then be attached to a gameObject?
I know that if a script doesn't inherit from monoBehaviour that it can be run without a gameObject.
I have an Account class which contains an array of Player class scripts. Player[] team;
These players store a bunch of stats are created within a gameManager script. Later within that gameManager script gameObject representations of these players are created, and the player script is attached to them. Therefore I need the player script to exist independently of a gameObject.
Account doesn't inherit from MonoBehaviour, but Player and GameManager currently do.
Could a scriptable object be my solution? Do I need to use static classes?
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 kannan21 · Jul 03, 2014 at 08:15 AM
Monobehaviours cannot be created before adding to gameobject. It can only be added to gameobjet and then and then only we can use it. This is not allowed by unity, it's restricted.
for(int i=0; i < numberOfPlayers; i++)
{
Player tempPlayerScript = playerModels[i].AddComponent<Player>();
}
Add the player to each gameobject like this. you don't need scriptable objects for this. What you did was right.
That just doesn't feel right to me. There has to be SO$$anonymous$$E way to use scripts without a gameObject.
If I add it to an object does that object always need to exist for the script to keep its variables or can I just add it once to a gameObject and be done with it?
If not would the best solution be to add a gameObjct PlayerRepresentation within the account script and store all the gameObjects there?
You can make the player class not mono then you don't need it be attached to a game object. Your player class is just a set of data so you dont need it to be mono. Just create it as a class and then
you can use it by not adding to to the gameobject and still can see it in the inspector by marking it as serializable class.
Answer by Kiwasi · Jul 04, 2014 at 12:21 AM
Simple enough to do. You need a MonoBehaviour attached to your GameObject to behave as a wrapper for your custom class. Something like this:
public class ContainerClass : MonoBehaviour{
public Account account;
// Assign account in the normal fashion
// Access account data and functions however you like
}
public class Account {
// Do whatever you want here
}
(Note, I didn't actually read through to figure out how you could fit this into your script, should be easy enough to adapt).
You can go even further and have the Update() method of your container call a Update method on your Account. Some with the other methods. You end up with everything that you get from a monobehaviour, plus standard design features available to classes.
This seems like it might be able to work, but could you be a little more specific?
It would be with the Player class, and I assume the container would be attached to the gameObject. Would I just duplicate all the variables between classes or would I put accessor methods within the container? I would create the regular method at runtime, and then create the wrapper as needed for the representation?
This feels a little hacky to me but I think it might work.
Do you think it is a better solution then storing the Players within gameObjects at all times?
It is a little hacky, I'm still figuring out the exact details on my own system. $$anonymous$$y application is a little different though, I'm using a bunch of internal classes inside a $$anonymous$$onoBehavior. The $$anonymous$$onoBehavior then switches between them using a static class.
There are other ways to code this sort of thing too. If its just data your after you can simply hand it off to a regular monobehaviour at the right time. Or you can keep it all on a controller class.
Let me think about more specific implementation details and get back to you.
Your answer
![](https://koobas.hobune.stream/wayback/20220613153056im_/https://answers.unity.com/themes/thub/images/avi.jpg)