Is there a way to toggle some parts of a script on/off in the inspector?

Hi there :slight_smile:

I’m pretty new to Unity and C#, but I’m slowly trying to learn while playing around with a small game project.

In the game there are several resources. To exemplify here lets use the following:

  • Wood
  • Stone
  • Iron

I’ve made a building script to each of the resources, so that i can make a building cost 10 wood for example.
I also tried making one where a building would cost 10 wood and 10 stone.
The problem I have is that if I do the latter and I only want a building to cost Wood, in game it will say “cost: 10 wood, 0 stone”.

Is there a simple way to make some public variables like floats and doubles inactive by a toggle function in the inspector?

Or just a way to make it ignore the value if the inspector field is empty or has 0 as it’s value?

Thank you for reading. I hope my question makes sense.

Spontaneously I would say:

public bool SkipThisArea = false; //In the insepector you can set it to true for other purposes

public void YourRoutine()
{
if (SkipThisArea == true)
{
return;
}

//if returned the following code below will not be executed

}

Or a not assigned object

if (ObjectForSkipping == null)
{
return;
}

you can toggle to disable fields in the editor to hide variables but unless you save that state directly in the class itself Editor state won’t persist over to the build. also doing so is unnecessary.

if you group all your resource costs in a dictionary<ResourceType,float> you can enumerate that dictionary and only print for values that are not 0. you can then use a stringbuilder to format together the Key (resource type) and the value (the cost with that resource). should also help to keep things simple in the inspector as you can balance in new costs for an item rather easily.

I have no idea what half of the things you’re saying mean, or at least not how to do it, but it sounds like what I’m looking for :slight_smile:
Good to know that it’s actually possible without having to jump through too many hoops anyhow. I’ll try to read about dictionaries and stringbuilders :slight_smile:
Thanks alot mate!

That seems nice and simple :slight_smile:

Just to clarify:
Lets say I have a “Public double wood = 0”.

If it then put in “wood;”
After the “return;” it will be deactivated if i check the bool?
Exactly what does “return” do?
That’s what I find hardest about learning this stuff… To find out what all the various commands do. And the unity API is very hard to navigate for a noob like me :stuck_out_tongue:

But thanks mate!

With a bit of training and searching for some code snippets, C# is not so hard to learn. It took me some months to get advanced in C#.

Your commands are processed one after another. If there is a return, you leave the methode or function at that point, without continuing and processing the commands after the return;

command A;
command B;
command C;

return;

command D; //won’t be executed
command E; //won’t be executed.

If there is no ‘void’ in the function, but a double, float, bool or int, you have to return plus an appropriate value.

public int SomeValue()
{
return 1;



}

At the attached script you can choose the path or the initialization which should be followed. For debugging you can do other things.

Maybe this get it a bit clearer.

public enum WhatToBuild
{
    Hut = 0,
    Tower = 2,
    Castle = 3
};


public class Build : MonoBehaviour {

    public bool IsInDebugMode = false; //In the inspector you can change it and set it true;
    public int Stone = 10;
    public int Wood = 10;

    private WhatToBuild BuildAction; //Determined by player's action

  
    void Start ()
    {
      
    }
  
  
    void Update ()
    {
      
    }

    public void BuildScriptWhichProofesIfThePlayerHasAllRequirements()
    {
        if (IsInDebugMode == true)
        {
            //Choose another path, for example ignore the requirements and let the player build.

            if (BuildAction == WhatToBuild.Hut)
            {
                SubtractFromCollectedResources(5, 0);
            }
        }
        else
        {
            //Normal way
            if (BuildAction == WhatToBuild.Hut)
            {
                SubtractFromCollectedResources(5, 0);
            }
        }
    }

    public void SubtractFromCollectedResources(int wood, int stone)
    {
        if (IsInDebugMode == true)
        {
            return;
            //Effectively it will not cost resources because the code below will not be executed
        }

        Stone -= stone;
        Wood -= wood;
    }

}

here’s an example .

using UnityEngine;
using System.Collections;
using System;

public enum resources{wood,stone,iron}

[Serializable]
public class need_resources
{
    public resources needed_resource;
    public int need_amount;
}

public class mytest : MonoBehaviour
{
    [SerializeField]
    need_resources[] my_resources_needed;

    // Use this for initialization
    void Start()
    {
        for(int i=0;i< my_resources_needed.Length;i++)
        {
            Debug.Log(my_resources_needed[i].needed_resource.ToString()+","+my_resources_needed[i].need_amount);
        }
    }   
}

regards.

Thank you :slight_smile:

In this example, would i then be referring to the resources in a seperate script?
With a wood, stone and iron script I mean?

What is the function of the debug.log? Do that have any impact on the game it self or is it only for the consolle to display a certain message? I never really understood when and why you’d want to code debug.log

Thank you for your elaborate example :slight_smile:
What is the point of the debug aspect in the script?
Is it to create a “test-mode” where i can enable a debug mode where everything is free to check if it works?

At my current state I think it’s better for me to keep it simple :slight_smile: When testing i just add alot of resources to the starting point instead.

In your example is the following code snippet a separate script?

public enum WhatToBuild
{
    Hut = 0,
    Tower = 2,
    Castle = 3
};

it is a debug console message it is not game related, it was there to just to show you it works and how you can iterate over all the resources .

you may place the resources enum and class in a seperate file , make sure to include the “using system” , then you can just add the serializefield and array to each building or whatever you need it to be used for , so that you can choose and add/setup only the types you need.

i do not know what you mean with different scripts like wood iron etc , i dont have enough information on what they are in your project.

i am sure you can figure it out :slight_smile:

Made it work, and it is exactly this kind of customization-options i was looking for :slight_smile:

A new problem has arisen though :stuck_out_tongue:

I have made it so that I can pick what type of resources my buildings require and how many.
But I cant figure out how to call these values, so that I can actually use them in another context.

An example from my script:

public class buildingManager : MonoBehaviour {

public enum resources { food, wood, }
private double baseCost;

[Serializable]
public class resourcesRequired
{
public resources cost;
public double amount;
}

[SerializeField]
resourcesRequired[ ] resourcesNeededToBuy;

void Start ()
{
for (int i = 0; i < resourcesNeededToBuy.Length; i++) ;
}

This allows me to pick the kind of resources the building need and how many of those resources are required to build it.
But how do I actually call these values (cost and amount) so that I can use them to substract from my total resources and so on? Right now I cant find a way to use them together with other variables (namely a double, which is the most important part).
Do my question make sense?

i can only give you examples ,and hope you find something within it to understand.

using UnityEngine;
using System.Collections;
using System;

//this can be in a seperate file if you want
//gameresources.cs
public enum resources{wood,stone,iron}

[Serializable]
public class need_resources
{
    public resources cost;
    public int need_amount;
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

//this would be a simple example of how you keep record of resources and manage them
//you only need one of these components active
//resource_manager.cs
public class resource_manager : MonoBehaviour
{
    public Dictionary<resources,int> my_collected_resources =new Dictionary<resources, int>();

    public static resource_manager Instance;


    //decrease the amount of a certain type of resource
    public void decrease_resource(resources resource_type,int amount)
    {
        if(my_collected_resources.ContainsKey(resource_type))
        {
            if( (my_collected_resources[resource_type]-amount) >-1)
                my_collected_resources[resource_type]-=amount;
        }
    }
 
    //increase the amount of a certain type of resource
    public void increase_resource(resources resource_type,int amount,bool add_if_not_added=true)
    {
        if(my_collected_resources.ContainsKey(resource_type))
        {
            my_collected_resources[resource_type]+=amount;
        }
        else
        {
            if(add_if_not_added) my_collected_resources.Add(resource_type,amount);
        }
    }
 
    //how many of this resource type is collected?
    public int amount_of_resource(resources resource_type)
    {
        if(my_collected_resources.ContainsKey(resource_type))
        {
            return my_collected_resources[resource_type];
        }
        return 0;
    }

    void Start()
    {
        Instance=this;
    }
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

//this would be a simple example of a building's resource requirements and how it can be handled
//building_manager.cs
public class building_manager:MonoBehaviour
{
    [SerializeField]
    public need_resources[] my_resources_needed;

    //returns false ,if any of the total resources, the player needs ,is not enough
    //returns true, if all needed resources, the player needs enough
    public bool have_enough_resources()
    {
        //loop through the amount of resource types this building has
        for(int i=0;i<my_resources_needed.Length;i++)
        {
            if(resource_manager.Instance.amount_of_resource(my_resources_needed[i].cost)<my_resources_needed[i].need_amount)
            {
                //player did not have enough resources
                return false;
            }
        }
        return true;
    }

    //building is being build
    public void build_building()
    {
        //not enough resources?
        if( ! have_enough_resources()) return;

        //remove the resources from the players resources
        //an exchange takes place
        for(int i=0;i<my_resources_needed.Length;i++)
        {
            resource_manager.Instance.decrease_resource(my_resources_needed[i].cost,my_resources_needed[i].need_amount);
        }
        //build the building or whatever..
    }

}

to add resources ,you could ,somewhere in your game when player collected a resource do something like this:

resource_manager.Instance.increase_resource(resources.iron,1);

p.s completely untested ,out of my head examples.

1 Like

I’ve tried for a few hours now to make it work. Got the “main” script to work (or at least show now errors), but I think this is still a bit above my paygrade, so I think I’ll just have to make do with a ton of smaller scripts. At this moment I simply cant wrap my head around how to activate those “collections” of variables in other scripts.
Thank you very much for the advice and help anyhow! :slight_smile: I’m very impressed with how nice this community is.

i think this is what your asking for ,if it is , then you do not need to mind the other script examples i previously posted because they will not lead you to know how to access the array via other scripts , instead then , do not over complicate things for your self by using them .

accessing a component script from another gameobject has many solutions , it all depends on what you need to do , therefore i provide you with a couple of them cramped into one script.

in this example , i created a gameobject and attached the building_manager script to it and named the gameobject “house building” and set its tag to “house building” , then i created a seperate object ,and attached this example to it ,and dragged the house building in to its slots, when you press play ,you should see the debug logging messages to show the methods all achieve the same end result.

you only need one of the methods ,depending on what you need to do, as you can see , each method is able to access the other gameobject’s building_manager script and then access the resources_needed[ ] array of cost and amount ,as you needed.

click for scipt

using UnityEngine;
using System.Collections;

public class howtogetvalues : MonoBehaviour
{

    //this is for method4
    public GameObject my_house3;

    //this is for method5
    public building_manager bm4;

//i only used start for convenience
//you apply one of these methods when and where you need it
    void Start()
    {
        print("--------method 1 test result--------");

        //method 1 (find one or first by name)
        GameObject my_house=GameObject.Find("house building");
        if(my_house!=null)
        {
            building_manager bm=my_house.GetComponent<building_manager>();//retrieve the building_manager
            if(bm!=null)
            {
                //now you can access the array inside building manager
                //depending on what you need to do
                //need_resources[] local_copy=bm.my_resources_needed;
                for(int i=0;i<bm.my_resources_needed.Length;i++)
                {
                    print(bm.my_resources_needed[i].cost +","+ bm.my_resources_needed[i].need_amount);
                }
            }
        }

        print("--------method 2 test result--------");

        //method 2 (find one or first by tag)
        //this needs a tag defined & attached to the object you want
        GameObject my_house1=GameObject.FindGameObjectWithTag("house building");
        if(my_house1!=null)
        {
            building_manager bm1=my_house1.GetComponent<building_manager>();//retrieve the building_manager
            if(bm1!=null)
            {
                for(int i=0;i<bm1.my_resources_needed.Length;i++)
                {
                    print(bm1.my_resources_needed[i].cost +","+ bm1.my_resources_needed[i].need_amount);
                }
            }
        }

        print("--------method 3 test result--------");

        //method 3 (find all by tag)
        GameObject[] my_houses=GameObject.FindGameObjectsWithTag("house building");
        if(my_houses.Length>0)
        {
            for(int this_house=0;this_house<my_houses.Length;this_house++)
            {
                building_manager bm2=my_houses[this_house].GetComponent<building_manager>();//retrieve the building_manager
                if(bm2!=null)
                {
                    for(int i=0;i<bm2.my_resources_needed.Length;i++)
                    {
                        print(bm2.my_resources_needed[i].cost +","+ bm2.my_resources_needed[i].need_amount);
                    }
                }
            }
        }

        print("--------method 4 test result--------");

        //method 4 (by dragging the object in the editor in to the slot)
        if(my_house3!=null)
        {
            building_manager bm3=my_house3.GetComponent<building_manager>();//retrieve the building_manager
            if(bm3!=null)
            {
                for(int i=0;i<bm3.my_resources_needed.Length;i++)
                {
                    print(bm3.my_resources_needed[i].cost +","+ bm3.my_resources_needed[i].need_amount);
                }
            }
        }

        print("--------method 5 test result--------");

        //method 5 accesses the building_manager directly (by dragging the object in the editor in to the slot)
        if(bm4!=null)
        {
            for(int i=0;i<bm4.my_resources_needed.Length;i++)
            {
                print(bm4.my_resources_needed[i].cost +","+ bm4.my_resources_needed[i].need_amount);
            }
        }

    }
   
 
}