Hi, I’m creating an RTS and been having a few issues but nothing that google hasn’t solved so far.
In this case, I’m having some trouble with checking the cost of the building I would like to create, and if creating it won’t put the player’s resources below zero. Pretty basic stuff, however it’s not working properly, only when the resources are below zero do I get the correct prompt that the building cannot be created.
Here’s the base class:
public class Building : MonoBehaviour
{
public int[] cost;
public GameObject build;
public int buildingID;
public int lCost { get { return cost[0]; } set { cost[0] = value; } }
public int sCost { get { return cost[1]; } set { cost[1] = value; } }
public int mCost { get { return cost[2]; } set { cost[2] = value; } }
void Start()
{
}
}
Here are the two child classes, each in its own script:
public class House : Building
{
public int LumberCost;
public int StoneCost;
public int MoneyCost;
void Start()
{
cost = new int[] { LumberCost, StoneCost, MoneyCost };
buildingID = 1;
}
}
public class TownHall : Building
{
public int LumberCost;
public int StoneCost;
public int MoneyCost;
void Start()
{
cost = new int[] { LumberCost, StoneCost, MoneyCost };
buildingID = 2;
}
}
The appropriate script is attached to each prefab along with the Building script.
Now I choose which building to create by using a dropdown list which calls the function in the placement script and sends the correct gameobject to create. Then I create a Building instance from getting the component from the sent gameobject and check if the cost of creating it won’t put the player’s funds below zero, and hold this as a bool which if it’s true, I instantiate the object, otherwise print a message.
Now my problem the way I think of it, is that I’m creating a Building instance instead of House or Town Hall, so the cost values are never really initialized in the Building class, meaning that the values that are checked are null. The reason I’m doing this is that I want it to be more generic rather than checking right away the name of the gameobject and initializing the appropriate class which would probably solve this.
This is the function in my placement script that gets called when the build button is pressed:
public void setItem(GameObject g)
{
Building tempBuilding = g.GetComponent<Building>();
if ((player.Lumber - tempBuilding.lCost >= 0) && (player.Stone - tempBuilding.sCost >= 0) && (player.Money - tempBuilding.mCost >= 0))
{
enoughFunds = true;
}
else
{
enoughFunds = false;
}
if (enoughFunds)
{
buildingObject = g;
isPlaced = false;
currentBuilding = ((GameObject)Instantiate(g)).transform;
currentBuilding.gameObject.name = currentBuilding.gameObject.name.Substring(0, currentBuilding.gameObject.name.IndexOf("("));
buildingType = tempBuilding.name;
}
else
{
StartCoroutine(ShowMessage("Not enough funds to build this.", 2.0f));
}
}
There’s more stuff in there but keeping it simple since they aren’t really relevant. Then in the update function if currentBuilding isn’t null, then the appropriate things happen. Basically I check the name of the gameobject and initialize the intended child class, subtract the cost from the player’s funds, and place it. There are checks of course for collision, and if the correct mouse button is pressed, but all that works fine.
So I would like some advice about this cause I would really like to avoid initializing the specific child class in setItem(), and instead initialize the parent like I do now in order to have it be more generic, and maybe even avoid initializing the child classes in my update function as well if there’s a way around this.
Thank you.