Classes and scripting organization

Hello everybody,
I’m a new Unity scripter. After reading the beginner and intermediate lessons about scripting, after tutorials, I want to create a simple game just to have a little practice.

This game will be a tapping one. You have to click (or to tap on mobile) the “screen” to kill one by one monsters.

I have no graphics (my enemies are just a cube, a sphere, etc…) because I just want to script.

I’ve started with simple things and a little bit I’m adding stuff.

Actually I need an advice because I think that my scripts (two) are too disorganized.

I have two scripts one is for prefab enemis (called enemy.cs) and the other one is for managing these enemies and other things like coins ( that will be needed to improve the player damage), but because I read that a class should only do one thing and only one, well I need this advice from you.

using UnityEngine;
using System.Collections;

public class Enemy : MonoBehaviour {

    public int enemyHealth = 10;                    // Base enemy life

    static int count = 0;                            // Counter to know how many monster have been created (and which is the difficult level
    static float gK = 0.015f;                        // Const used to raise monster life
    static int coin = 10;                            // How many coins the monster will drop, actually it does not increase.
    static ManagingEnemies managingEnemies;            // Here will be the reference to the ManagingEnemies script.

    void Awake ()
    {
        managingEnemies = GameObject.FindGameObjectWithTag("GameController").GetComponent<ManagingEnemies>();            // Take reference to the other scripts
    }
    void Start ()
    {                                   
        enemyHealth = EnemyLife ();                                                    // On start the it will be assigned the enemy life as the function below does.

    }

    private int EnemyLife()
    {
        float tempH = enemyHealth * ( 1 + NumberPower((count++ - 1),2) * gK );        // The function which calculate the increasing of enemy's life
        return (int)tempH;
    }


    public void TakeDamage(int damage)                                                //Function which manage the damage took.
    {
        if (enemyHealth > 0)
            enemyHealth -= damage;
        else if(enemyHealth <= 0)
            Death();
     }

    private float NumberPower(float number, int index)                                // exponentiation function. I dunno if there is already one.
    {
        for (int i = 0; i < index; i++)
            number *= number;
        return number;
    }

    private void Death()                                                            //When the monster dies, this function gives the coin to the player and destroy the old monster.
    {
        Destroy (gameObject);
        managingEnemies.AddCoin (coin);

    }




}
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ManagingEnemies : MonoBehaviour {

    public GameObject[] enemyObj;                 // Here there is an array with monster prefab. On each monster prefab there is an enemy.cs script
    public Text text;                            // Text item to count the coins


    GameObject enemyInstance;

    private int damage = 1;                        // Actual damage
    private int coin = 0;                        // Starting coin
    private Enemy enemy;                        // Variable to get the reference to the enemy script

    void Awake ()                                 // On Awake I take the reference to the text item and I update it
    {
        text = GameObject.Find ("Coin").GetComponent<Text> ();
        UpdateCoinText ();

    }
       
    private void UpdateCoinText()                 // Function created to update coin text
    {
        text.text = "Coin: " + coin;
    }

    void Update()                                // Each update if there is no enemy instance a new one will be created, if player tapped call the Tap() function
    {
        if (enemyInstance == null)
            CreateEnemy ();           
        if (CheckTap ())
            Tap ();
       
    }

    void CreateEnemy()                            // As the name says, this function creates a new enemy instance and takes the reference to its script.
    {
        enemyInstance = Instantiate (enemyObj[Random.Range (0, enemyObj.Length)], new Vector2 (0, 0), Quaternion.identity) as GameObject;             // Instantiate a random monster among those referenced.
        enemy = enemyInstance.GetComponent <Enemy> ();

    }
   
    private bool CheckTap()                        // Simple...but..maybe useless?
    {
        if (Input.GetMouseButtonDown (0))
            return true;
        return false;
    }

    private void Tap()                            // If the enemy reference is not null, the enemy takes damage, using enemy class
    {

        if (enemy != null)
            enemy.TakeDamage(damage);   

    }

    public void AddCoin(int amount)                // Functions to add or subtract coins.
    {
        coin += amount;
        UpdateCoinText ();
    }

    public bool SubCoin(int amount)
    {
        if (amount >= coin) {
            coin -= amount;
            UpdateCoinText ();
            return true;
        }
        return false;
    }




   


}

Maybe this is a long post…but please, I really want to improve my skills…
Thank you

If you think your code is too disorganized, and you are having trouble reading it, then it probably is. I use a combination of things to help organize my code a little better. Basically, what you want to do is group similar things into regions and note their usage with comments. Moreover, separate things that are related even further into different classes.

You dont appear to be using enemyObj?

Not sure that has anything to do with the OP’s question of how to organize code :-p

1 Like

I often have scripts hundreds of lines long, so I use certain rules regarding indentation and placement of brackets/curly braces and ellipses to help my code look better and be more navigable and easy to read. Too little space can make it very difficult to find what you are looking for, and too much is also hard to grasp.

#1: For brackets/curly braces, if there are more than four lines of code within the brackets, I place the opening bracket on the next line, else, I put it at the end of the same line with no space.
#2: I always put one empty line in between separate thoughts, while keeping related statements grouped together.
#3: I basically just try to follow the same practices for everything. It becomes another type of syntax, but an aesthetic syntax.
#4: Last but not least, just code a lot. It will come to you in time, and you will develop your own set of aesthetic grammar rules that make your workflow fast and efficient.

Here is a short example of how I structure my code.

// over four lines
foreach(Type individual in group)
{
   // under five lines
   if(individual == testItem){
      string text = "Found Item: " + individual.ToString();
      Debug.Log(text);
   }

   // single line, no brackets required
   if(individual == null) return;

   // double line, no brackets required, but more space due to the amount of information being handled
   if(individual != null  && individual != testItem && testItem != null)
      Debug.Log("Individual is not equal to " + testItem + ".");
}
1 Like

At the risk of starting a flame war - If statements without braces are in my opinion never a good thing. The only exception being when they are followed by a return.

In your third example, what happens if you wanted to add an extra debug line or something?

also you should get rid of the visual clutter of commenting too much, no point in commenting about what is obvious about things via the Method and Variable names. Comments should be more about reminding you of your intention behind things, not restating what things are.

1 Like

I do like the other guys code but I agree with the braces. I always use braces even if they only enclose one line. It’s a personal preference thing though. I do it for the reason you mentioned. What if I want to add to that block?

Then you simply add braces.:eyes:

3 Likes

Thanks a lot for all your comments.

Well I don’t think that the code is disorganized but I have fear of it :smile:

I used to be a programmar in other languages long time ago (about 6/7 years ago) and I never knew if my way of thinking in OOP is ok or not…I just wanted to have a comparison with other programmers that are better then me :slight_smile:

What an astute observation. That’s why I add them from the start to avoid the hassle of having to navigate around the line that is already there. Adding them from the start saves me at least a second in time for each block I need to go back and add braces to later. I’m all about efficiency haha

but there are also a lot of situations when you know you will not need more than 1 line in the conditional. Such as for a return, or if null checks. Also a lot of cases when a ternary can be used in place of a if.

1 Like

The thing is, braces are explicit - the code in here will only be executed if this statement is true.
Clear code is much better than saving what, one line? (If you do Java style braces) When browsing over a lot of code (believe me I have done this) and are trying to get a grasp of it, it is a lot easier to see program flow. Braces aid understanding of flow. If you develop in a larg(ish) team you will really understand this.

The only exceptions are conditionals that return immediately (old school null pointer checks in c++ come to mind) and conditionals that break loops.

1 Like

It’s really just my personal preference. I format my code by starting the braces on the same line as my statement so it doesn’t really add any clutter and it only adds one extra line. It’s easier for me to read that way. Nobody formats their code exactly the same as someone else.

#nailedit

more like indentation, its far faster and easier to understand the spatial information than it is to watch for braces. When it comes to trying to wrap the human mind around the flow.

At least we can agree on there is no point in commenting the obvious that can be understood by using good names.

Yeah, probably a combination of both I thing. But yeah this is a hot topic, with many opinions right! Comments I agree on though. Comment should by why, not what.

Alright, it’s clear that this is just going to start a code formatting war. I’m finished. It’s like a religion; everyone prays to their own formatting god because you were raised on His teachings or find them easier to follow. I think it’s best if we just say we’re all right and not spill any blood over this. Point is, do what works for you. Organize it to the best of your ability and any other programmer is going to be able to read it; programmers aren’t stupid.

its because it comes from peoples roots if you got a java, c++ or say a ruby or python background. Really influences how people like to do things.

The same war could be started between implicit or explicit in many other things like the encapsulation level.
Whats important is your intent can be understood, and that your team works well together.

Keep the intent clear, comment the intent if needed. Keep good encapsulation, and make sure you got 1 responsibility per class.

1 Like

Agreed. I started out programming for web many years, so I tend to format things in more of a Javascript style, though I never use Javascript anymore because I prefer C#.