Search Unity

Resource Counting

Discussion in 'Scripting' started by Skyfall106, Sep 16, 2017.

  1. Skyfall106

    Skyfall106

    Joined:
    Mar 5, 2017
    Posts:
    132
    Hey. Im trying to make a Resource manager. I have a system where you can chop down trees but I want ot make it so you get wood if it is fallen. I have referenced the UI and made an int but I cant figure out how I can detect if a tree has been fallen. I will reference my Tree script (The collider has a tag for the axe to work)

    Code (csharp):
    1.  using System.Collections; using System.Collections.Generic; using UnityEngine;
    2.  
    3. public class Tree : MonoBehaviour { //Variables GameObject thisTree; public int treeHealth = 5; public bool isFallen = false;
    4.  
    5. [LIST=1]
    6. [*]public void Start()
    7. [*]{
    8. [*]     thisTree = transform.parent.gameObject;
    9. [*]}
    10. [*]public void Update()
    11. [*]{
    12. [*]     if(treeHealth <= 0 && isFallen == false)
    13. [*]     {
    14. [*]         Rigidbody rb = thisTree.AddComponent<Rigidbody>();
    15. [*]         rb.isKinematic = false;
    16. [*]         rb.useGravity = true;
    17. [*]         rb.AddForce(Vector3.forward, ForceMode.Impulse);
    18. [*]         StartCoroutine(destroyTree());
    19. [*]         isFallen = true;
    20. [*]     }
    21. [*]}
    22. [*]public IEnumerator destroyTree()
    23. [*]{
    24. [*]     yield return new WaitForSeconds(10);
    25. [*]     Destroy(thisTree);
    26. [*]}
    27. [/LIST]
    28. }
    29.  
    30.  
     
  2. Invertex

    Invertex

    Joined:
    Nov 7, 2013
    Posts:
    1,546
    Just make the isFallen a variable of that script which other scripts can look at. `public bool isFallen;'.
     
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    You're already detecting if a tree has been fallen in line 19 of the above script.

    So I think your real question is, how do you update your count of trees fallen (which is basically like a score)?

    There are lots of ways to tackle this; if you work through a few of the tutorials, you'll see several methods. But here's what I would probably do.
    1. Define a ResourceManager class (a MonoBehaviour), which follows the standard Singleton-like pattern of having a public static instance that returns a reference to the single ResourceManager in the scene.
    2. Create an empty GameObject in the scene and attach ResourceManager to it. At this point, any script in the scene can get a reference to that thing just by using ResourceManager.instance.
    3. Give ResourceManager an AddWood() method, and of course an integer field for storing how much wood it has.
    4. In your Tree script, right around line 19 where you've detected the tree is fallen, call ResourceManager.instance.AddWood().
    5. Also give ResourceManager a string UnityEvent (please see my tutorial on UnityEvent, and if it's still unclear how to create a string event, just ask) for when the amount of wood has changed. Invoke this event from AddWood.
    6. Finally, in the UI, hook this event up to your Text object that should display the amount of wood.
    Note that a string event isn't really ideal here; it should be an integer event, but then you'd need another script to convert that to a string for display. I have a standard script that does exactly that, so by this point I can just snap these things together like Lego... but for getting started, a string event is simpler and should be just fine.

    There are of course many variations on this pattern that would work, but this is my suggestion.
     
  4. Skyfall106

    Skyfall106

    Joined:
    Mar 5, 2017
    Posts:
    132
    I did my best to follow what u said but I am still having trouble. The best i could get upto in my code is this and im not sure where I went wrong. (Im still learning)

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. public class ResourceManager : MonoBehaviour {
    8.  
    9.     public Canvas canvas;
    10.     public Text wood;
    11.     public int Wood;
    12.     public Text stone;
    13.     public int Stone;
    14.  
    15.  
    16.  
    17.     // Use this for initialization
    18.     void Start () {
    19.        
    20.     }
    21.    
    22.     // Update is called once per frame
    23.     void Update () {
    24.  
    25.  
    26.  
    27.     }
    28.  
    29.     public void AddWood()
    30.     {
    31.        
    32.     }
    33. }
    34.  
    35.  
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    You didn't setup the singleton.
    Code (csharp):
    1.  
    2. public static ResourceManager instance;
    3. void Awake() {
    4.    if(instance == null) instance = this;
    5.    else if(instance != this) Destroy(gameObject);
    6.    }
    7.  
    and there's no code in AddWood() ? :)
    You maybe want something like...
    Code (csharp):
    1.  
    2. void AddWood(int cnt){
    3.    wood += cnt;
    4.    woodText.text = wood.ToString(); // yes, I changed the variable name, but you can use whatever you prefer.
    5.   }
    6.  
    Then, you'd call:
    Code (csharp):
    1.  
    2. // wherever you're collectin/chopping down.
    3. ResourceManager.instance.AddWood(2); // adds 2 wood to your score or what not.
    4.  
    I didn't include an event example. Event is very useful once you have more than 1 (or maybe 2) separate places you want to update. I mean, it's never bad with 1.. but.. anyways -- helps more if you have more to "notify" imho.
     
    JoeStrout likes this.