Instantiate with constructor is it possible?

Hi guys,
I need an advice…I’m trying to reorganize some scripts in my personal game project “Do it so you will learn” =P

In this project I need to instantiate a prefab enemy one by one (so when the first enemy will die, the seconds will be instantiated).

I want to pass some argument when the enemy is created, I know that a constructor functions with the “new” code i.e.:

public class Example {
       public int health;

       public Example(int baseHealth, int level)
       {
                  health = baseHealth * level;
       }
}

public class anotherClass
{
          Example ex;

          void Start() {
                 ex = new Example(500,2);
          }
}

But how to do when I have to instantiate a prefab and I want to pass arguments to the constructor?

Personally, I would use MonoBehaviours instead of Object class. That way when I instantiate an opponent with code:

public GameObject enemyPrefab;
public Transform spawnPoint;

public GameObject SpawnEnemy(int level, int hp)
{
     GameObject enemy = Instantiate( enemyPrefab, spawnPoint.position, Quaternion.identity) as GameObject;
    
     enemy.GetComponent<ActorController>().level = level;
     enemy.GetComponent<HealthComponent>().value  = hp;

     return enemy;
}

I can set all relevant data when he is instantiated. Not to mention using MonoBehaviour, you can inspect your script values in inspector whereas using just object would need extra work with serialisation to make it work if I’m not mistaken.

Please note this is just a basic example, personally I would use some other way to assign data to your enemy, like loading values from a database or something.

3 Likes

Hi Fajlworks and thanks for your reply.

Actually my function is this one:

    public void CreateEnemy()                           
    {
        enemyInstance = Instantiate (enemyObj [Random.Range (0, enemyObj.Length)], new Vector2 (0, 0), Quaternion.identity) as GameObject;             // Instantiate a random monster among those referenced.
        if (enemy == null) {
            enemy = enemyInstance.GetComponent <Enemy> ();
        }

    }

All values are calculated inside the Enemy class. Now I need to pass the enemylevel to enemy class because I wrote a saving and a loading functions so I need to pass the enemy level when I load…

Hmm, how does Enemy class look like? What is “enemylevel” you are referring to? Is it a int or another class? What are those saving and loading functions? Are those PlayerPrefs or your custom code?

Since you didn’t provide any extra info, I’ll assume you need:

public void CreateEnemy()                       
{
    enemyInstance = Instantiate (enemyObj [Random.Range (0, enemyObj.Length)], new Vector2 (0, 0), Quaternion.identity) as GameObject;             // Instantiate a random monster among those referenced.
    if (enemy == null)
    {
        enemy = enemyInstance.GetComponent <Enemy> ();
        enemy.level = 10; // I guess? O.o

       // or

        enemy.level = GameManager.Instance.currentLevel; // I assume GameManager loads/saves current level
    }
}
    enemyInstance = Instantiate(...);
    enemy = enemyInstance.GetComponent<Enemy>(); 
   
    if(enemy)
    {
        enemy.Initialise(...parameters...)
    }
//in enemy class

public void Start()
{
    /// setup stuff that isn't dependant on parameters
}

public void Initialise(...parameters...)
{
    /// setup stuff from the parameter values
}
1 Like

Ok :smile: I thought there was another way to declare a constructor or something similar =)

the unity game engine “constructs” GameObjects and Components and the like… I’m really not the one to comment on what it does internally for that to happen (voodoo and something to do with sacrificing virgin chickens I suspect). You’re not working directly inside that when you instantiate something, you’re just given the completed “thing” at the end of the instantiation.

1 Like

You can use a factory pattern to allow for constructor like behaviours

public class Factory : MonoBeheviour {

    bool isInitialised;

    void Start () {
         if(!isInitialised) {
             Debug.LogError("component can only be created with factory method", this);
             Destroy (this);
             return;
         }
    }

    public static void AddFactory (GameObject target, ...) {
        Factory clone = target.AddComponent<Factory>();
        // Do initialisation
        clone.isInitialised = true;
    }
}
2 Likes