variables adding up between objects with same script

hello all, and thanks in advance. I made a small piece of script for a space game I am working on, the code is to attach to my planet prefabs to hold some info about the planet. The code works great for one object, but when I add more planets they add the new values to the old one rather than just keeping it all separate. Anyway here is my code

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Planet : MonoBehaviour {

    public static int resources = 200;
    public int planetWealth;
    public  int planetSize;

    void Start ()
    {

        int randWealth;
        int randSize;
       

        randWealth = Random.Range(1, 3);
        if (randWealth == 1)
        {
            int res = resources;
            planetWealth = res / 4; // randomly decides if new planet is rich, middle, or poor
        }
        else if (randWealth == 2)
        {
            planetWealth = 0;
        }
        else
        {
            int res = resources;
            planetWealth = res / 4;
        }



        randSize = Random.Range(1, 3);
        if (randSize == 1)
        {
            int res = resources;
            planetSize = res / 4;
            resources = res + planetSize + planetWealth;// randomly sets if planet is Large, med, or small
        }
        else if (randSize == 2)
        {
            planetSize = 0 + planetWealth;
        }
        else
        {
            int res = resources;
            planetSize = res / 4;
            resources = res - planetSize + planetWealth;
        }

        Debug.Log("Planet Wealth: " + planetWealth);
        Debug.Log("Planet size: " + planetSize);
        Debug.Log("Planet Resources : " + resources);
        Debug.Log("Random Size" + randSize);//checking my values as i code
        Debug.Log("Random Wealth: " + randWealth);
    }

}

static variables are stored at the ‘class level’. For any static variable in the class, each instance of the class will access the same 1 variable.

1 Like

ah hah, thanks again its just when I look over my own code so much its easy to miss the small stuff static variables are accessing the actual area of memory correct?

not sure what “actual area of memory” means :slight_smile:

but I could show a quick example:

public class SomeClass {
 int a;
 string b;
 static float f;
}

If I have 20 ‘SomeClass’, each has its own ‘a’ and ‘b’ but there is only 1 ‘f’. :slight_smile:

1 Like

Static variables are used when only one copy of the variable is required, so it basically uses only one memory allocation.

1 Like

Thanks again, you all keep me rolling forward

Cool - enjoy yourself :slight_smile:

These are my mostly finished classes, I’m going to comment out a piece in the player script because that’s the next part it need help with. When my player who has a fleet which can Attack() and Defend() collides with a planet which also has a fleet how can I compare the attack to the defense and then based on those results subtract the correct health. really all I need is the ability to grab the total attack from the planet

Player Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {
    public Fleet playerFleet;
    int sloop = 20;
    int corsair = 10;
    int frigate = 5;
    int carvahal = 5;
    int warship = 2;

    // Use this for initialization
    void Start()
    {
        playerFleet = new Fleet(sloop, corsair, frigate, carvahal, warship);

    } 
   
    // Update is called once per frame
    void Update ()
    {
       
    }
/*
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("EnemyPlanet"))
        {
            if (playerFleet.Attack() > )
            {

            }
        }

    }
*/
}

Planet Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Planet : MonoBehaviour
{
    public Fleet planetFleet;
    public int resources = 200;
    public int planetWealth;
    public int planetSize;
    int numSloop;
    int numCor;
    int numFrig;
    int numCarv;
    int numWs;

    void Start()
    {
        RandomWealth();
        RandomSize();
        resources += planetSize + planetWealth;
        while (resources >= 5)
        {
            RandomFleet();
        }  
        planetFleet = new Fleet(numSloop, numCor, numFrig, numSloop, numWs);

       /* Debug.Log("Planet Wealth: " + planetWealth +
                  "\nPlanet size: " + planetSize +
                  "\nPlanet Resources: " + resources);
        Debug.Log("numSloop: " + numSloop +
                  "\nnumCor: " + numCor +
                  "\nnumFrig: " + numFrig +
                  "\nnumCarv: " + numCarv +
                  "\nnumWs: " + numWs);*/
    }
    private void Update()
    {
 

    }
    public void RandomWealth()
    {
        int randWealth;
        randWealth = Random.Range(1, 3);
        if (randWealth == 1)
        {
            int res = resources;
            planetWealth = res / 4; // randomly decides if new planet is rich, middle, or poor
        }
        else if (randWealth == 2)
        {
            planetWealth = 0;
        }
        else
        {
            int res = resources;
            planetWealth = res / 4;
        }
    }

    public void RandomSize()
    {
        int randSize;
        randSize = Random.Range(1, 3);
        if (randSize == 1)
        {
            int res = resources;
            planetSize = res / 4;
            // randomly sets if planet is Large, med, or small
        }
        else if (randSize == 2)
        {
            planetSize = 0 + planetWealth;
        }
        else
        {
            int res = resources;
            planetSize = res / 4;
        }
    }

    public void RandomFleet()
    {
        int randomShip;
        int sloopCost = 5;
        int corCost = 10;
        int frigCost = 10;
        int carCost = 15;
        int wsCost = 20;

        randomShip = Random.Range(1, 6);
        if (resources >= sloopCost)
        {
            if (randomShip == 1)
            {
                if (resources >= sloopCost)
                {
                    numSloop += 1;
                    resources -= sloopCost;
                }
            }
            else if (randomShip == 2)
            {
                if (resources >= corCost)
                {
                    numCor += 1;
                    resources -= corCost;
                }
            }
            else if (randomShip == 3)
            {
                if (resources >= frigCost)
                {
                    numFrig += 1;
                    resources -= corCost;
                }
            }
            else if (randomShip == 4)
            {
                if (resources >= carCost)
                {
                    numCarv += 1;
                    resources -= corCost;
                }
            }
            else if (randomShip == 5)
            {
                if (resources >= wsCost)
                {
                    numWs += 1;
                    resources -= wsCost;
                }
            }
        }
    }
}

as soon as I finished those nested if else statements I wished I had just made them switches lol

Fleet class:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class Fleet
{
    public int numSloop;
    public int numCorsair;
    public int numFrigate;
    public int numCarvahal;
    public int numWarShip;

    public Fleet(int s, int cor, int frig, int carv, int ws)
    {
        numSloop = carv;
        numCorsair = cor;
        numFrigate = frig;
        numCarvahal = carv;
        numWarShip = ws;
    }
    // set up Ship objects

    public Ship sloop = new Ship(1, 2, 2);
    public Ship corsair = new Ship(5, 2, 2);
    public Ship frigate = new Ship(10, 4, 4);
    public Ship carvahal = new Ship(4, 10, 4);
    public Ship warship = new Ship(15, 10, 15);


    public int Attack()
    {
        int totalAttack;
        totalAttack = (sloop.attk * numSloop) + // collect attack power * numer of current ships
                      (corsair.attk * numCorsair) + // for each ship type
                      (frigate.attk * numFrigate) +
                      (carvahal.attk * numCarvahal) +
                      (warship.attk * numWarShip);
        totalAttack = Random.Range(0, totalAttack);// sets total defense to a random range to resolve battles and add a randomness to attacks
        return totalAttack;// returns total attack power for fleet

    }

    public int Defend()
    {
        int totalDefense;
        totalDefense = (sloop.defense * numSloop) + // collect Defense * numer of current ships
                      (corsair.defense * numCorsair) + // for each ship type
                      (frigate.defense * numFrigate) +
                      (carvahal.defense * numCarvahal) +
                      (warship.defense * numWarShip);
        totalDefense = Random.Range(0, totalDefense);
        return totalDefense;// returns total Defense for fleet

    }

    public int Health()
    {
        int totalHealth;
        totalHealth = (sloop.health * numSloop) + // collect health * number of current ships
                      (corsair.health * numCorsair) + // for each ship type
                      (frigate.health * numFrigate) +
                      (carvahal.health * numCarvahal) +
                      (warship.health * numWarShip);
        return totalHealth;// returns total Health for fleet

    }
  
}

sorry its such a long post, the ships class just stores an int for health, defense, and attack

When you engage, you can get the script from the planet and from there you can retrieve values. Is that what you mean?
I mean, it could be that your game works like: if fleet encounters planet fleet → do combat calculations → report results.
I’m not sure…

Do you want something like FleetsEngaged(Fleet fleet1, Fleet fleet2) { /* Do stuff */ }
or something else?

I have been working on this problem since I posted this and this is what I came up with

 void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("EnemyPlanet"))
        {
            Planet enemy = other.GetComponent<Planet>();
            int attk = playerFleet.Attack();
            if (attk > enemy.planetFleet.Defend())
            {
                enemy.planetFleet.TakeDamage(attk);
            }
            else if (attk <= enemy.planetFleet.Defend())
            {
               
                playerFleet.TakeDamage(enemy.planetFleet.Attack());
            }
        }

    }

that is the part of the player class I commented out, also added this to the fleet script

 public void TakeDamage(int amount)
    {
        int rand = Random.Range(1, 6);
        while (amount > 0)

            if (rand == 1)
            {
                numSloop -= 1;
                amount -= sloop.health;
            }
            else if (rand == 2)
            {
                numCorsair--;
                amount -= corsair.health;
            }
            else if (rand == 3)
            {
                numFrigate -= 1;
                amount -= frigate.health;
            }
            else if (rand == 4)
            {
                numCarvahal -=1;
                amount -= carvahal.health;
            }
            else if (rand == 5)
            {
                numWarShip -= 1;
                amount -= warship.health;
            }
    }

basically my game is this: fly to a planet which you can fight fleet vs fleet, if the planet fleet is destroyed the player owns that planet which will produce ships they can add to there fleet. In the end I intend to procedurally generate my planets in an area and make them steadily stronger as you get to the center when you capture the center planet it is game victory. it seems simple but I feel like I make everything too complicated. So I want it when they fight to remove the correct amount of ships from each fleet per battle. I may make this turn based or timer based I’m still unsure

And is that working well for you?

There’s 1 tiny (unrelated issue) I see with your code. If you had incoming damage, of say ‘100’.
Your warship is 80 and your frigate is 40. If the warship is hit, it’s destroyed (good), now ‘amount’ should be 20, and if you hit the frigate, it’s now killed the frigate instead of damaging it.
Err, you’re also only getting the random number once (making my sentence partially invalid). Dunno if that’s on purpose or not :slight_smile:

Other than that, if it’s working … that’s great :slight_smile:
Sounds like a fun game.

The random number once was not intentional, is that due to my while loop? The intention was to make it work kind of in the reverse way I populated the planet fleet. I just didn’t want to take attack vs defense subtract health, because I wanted to just destroy ships in the fleet which will reflect in the total health, after I can make these two objects and scripts interact correctly I want to make on collision a new scene which will be the battle and I’m thinking turn based is my best option for the battles. if I were to throw another if statement to check if amount is >= to whatever ship it’s damaging before I destroy that ship that should fix my ships from dying from partial damage.

Yes, to the last part you wrote. If amount is less than their health, they’d be damaged but not destroyed.
And yes, to the while loop. You only calculate the random # once, so each “attack (session)” would only kill off 1 type of ship. If you did the random number inside the loop, … (random) types of ships would take damage from the attack :wink:

My code compiles perfectly, I got rid of the while loop and make my OnTriggerEnter into
OnTriggerEnter2d and also Collider2d, but my code for the two fleets to fight never happened. I have my player collider as a very simple 5 point 2d polygon and my planets are 2d circle collides set as a trigger, but I can’t seem to get the code to execute.

Okay, well does the OnTriggerEnter2D get called? One of them needs to have a rigidbody (for trigger, it can be kinematic or non-kinematic).

I have a rigid body on my player, though honestly right now I can remember if it’s a rigidbody2d, I put a debug.log in my on trigger function but it seems to never be called

Okay, well definitely check that you have the RIgidbody2D. :slight_smile:

Then, I’m not sure what to say if it’s not called. Make sure the area is big enough? You can post some code if you think that will help/could be a problem?