2
\$\begingroup\$

First off, please understand I am horrendously confused with how to do things in Unity. I might not even be asking the right questions, I'll pose my problem and hope it shows my gap in knowledge.

For my game project (a clicker game), I have a several types of object for the player to interact with. Food, Training Dummies, Enemies etc. As per most games, I need objects of the similar type to have different parameters. eg. blue enemy does 1 damage, red enemy does 2. Unlike most games, I will only be showing one 'interactable' object per scene. once you defeat that enemy, it dies, you get experience and it respawns. once you've eaten the food, it vanishes and you get whatever bonus and then it restocks based on what you have in your inventory.

So, I'd made a base class Enemy (which is a unity script, right? which is just a c# class you can attach to a GameObject?)

Next step, adding my child game objects into the scene when I need them. I think this is where the confusion sets in.

So far I'd placed a GameObject in my scene, set it's layout etc and attached the enemy script to it. my respawn mechanic (for a single enemy object repeating itself) was to access the canvasgroup component and set the alpha & interactivity off and then back on, the 'new' enemy would also have it's health refilled, the total updated, all inside a single script using one class. I'm doing it in such a primitive way because I can't quite understand how to correctly create a new child object into my scene and interact with it.

if I make a c# script "BlueEnemyScript" inherit from script "EnemyScript", that's a "child object" in c#?

I create a GameObject (Blue_Enemy) and attach all the components to it including BlueEnemyScript c# script, then drag it into prefabs.

I then have another GameObject called EnemyManage that will instantiate the prefab via a script.

When I instantiate this prefab (is that a Child in Unity?), it will have it's own unique instance of BlueEnemyScript?

If I were to instantiate the non child Enemy, but change it's parameters as part of the method to instantiate it, wouldn't it have the same effect since it has a unique instance of the script?

Do I even need multiple instances because I'll only have one of the same object type active at a time? should I just swap which method inside the object script is being accessed?

Happy to have this question closed, I understand it's a mess.

I read some old questions but they haven't made it much clearer:

\$\endgroup\$
2
\$\begingroup\$

if I make a c# script "BlueEnemyScript" inherit from script "EnemyScript", that's a "child object" in c#?

No, when you define something like public class BlueEnemyScript : EnemyScript, that's a "derived class". The class BlueEnemyScript "derives" or "inherits" from the "base class" or "superclass" EnemyScript.

A "child object" is when you nest one object under another in the Unity hierarchy, as shown in this image from the Unity docs:

Unity Hierarchy Window showing parent & child objects

In code it looks like this:

 myGameObject.transform.parent = parentGameObject.transform;

A prefab could be a child object, if you instantiate it under a parent/container of some kind, eg.

myInstance = Instantiate(myPrefab, parentTransform);

A prefab can also contain its own child objects - you can have a whole hierarchy of parts making up one compound object.

When I instantiate this prefab...it will have it's own unique instance of BlueEnemyScript?

Yes. Each copy you Instantiate or drag into your scene has its own instance of the script, and can have its own values of any of the script's member variables.

If I were to instantiate the non child Enemy, but change it's parameters as part of the method to instantiate it, wouldn't it have the same effect since it has a unique instance of the script?

Yes, I'd strongly recommend not creating new scripts if all you want to do is change parameters.

You could make one Enemy script with gobs of prefabs mixing & matching different sets of parameters or other components, to define lots of different monsters without redundant code.

Or you can change the parameters of the object in your script when you instantiate it. The effect is the same. Some developers prefer to do everything in script like this, others prefer to keep this variation in the data like prefabs so it's easy to modularly add new types without code changes (which can help with a larger team where not everyone is a programmer)

Do I even need multiple instances because I'll only have one of the same object type active at a time? should I just swap which method inside the object script is being accessed?

This is definitely an option too. You can even destroy or disable unneeded components and AddComponent or enable others to change up the behaviour without needing to implement multiple subclasses. This is the principle of composition over inheritance that Unity's component system banks on.

\$\endgroup\$
  • \$\begingroup\$ Thank you so very much for taking the time and energy to break this down for me, as you can tell I was lost in quite a few areas despite constantly reading documentation and forums. Given how easy it is to get started with unity and my lack of experience programming I'd managed to get quite far with creating something before I realised I didn't exactly know what was going on. \$\endgroup\$ – bumble Mar 4 '18 at 18:41
  • \$\begingroup\$ Did that cover what you needed? \$\endgroup\$ – DMGregory Mar 4 '18 at 18:47
  • \$\begingroup\$ I think so! I'll probably be back with another roadblock once I've applied these explanations and gotten some things implemented. \$\endgroup\$ – bumble Mar 4 '18 at 19:00
0
\$\begingroup\$

While I'm pretty novice I thought I would chime in too! (ofc i'm open to feedback too!) IMO it seems you're pretty close.

Rather than making multiple scripts to hold different enemies at this early phase, I agree with DMGregory's suggestion of using 1 prefab with different inputs.

After Instantiating the prefab enemy object I like to make a reference to the objects script in the EnemyManage object so i can call the different classes and assign values:

public GameObject EnemyPrefab;
public Enemy EnemyScript;
public void CreateBlueEnemy
{
    myInstance = Instantiate(myPrefab, parentTransform);
    EnemyScript = myInstance.GetComponent<Enemy>();
    EnemyScript.Damage = 1;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.