Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Score Manager

Discussion in '2D' started by BSacramento, Mar 13, 2018.

  1. BSacramento

    BSacramento

    Joined:
    Mar 13, 2018
    Posts:
    7
    I have a script that every time i pick up a coin it gives me one point, but sometimes instead it gives me two points instead, and i use a version of the same script to the HP and happens the same, sometimes gives double the damage. Its a very simple script and i can't find what can be wrong, any ideas?


    public class ScoreManager : MonoBehaviour
    {
    public static int score;


    Text text;


    void Awake ()
    {
    text = GetComponent <Text> ();
    score = 0;
    }


    void Update ()
    {
    text.text = "Score: " + score;
    }
    }


    --------------------------------------------end script---------------------------------------------------------------


    public class CoinScore : MonoBehaviour {


    void OnTriggerEnter2D (Collider2D other)
    {
    if (other.gameObject.tag == "Player")
    {
    ScoreManager.score = ScoreManager.score + 1;
    Destroy (GetComponent <SpriteRenderer> ());
    Destroy (GetComponent <BoxCollider2D> ());
    }
    else
    {
    return;
    }

    }
    }
     
    IronManBK likes this.
  2. Varishaa

    Varishaa

    Joined:
    Feb 19, 2018
    Posts:
    16
    Sure you dont have 2 coins at the same place that look identical and thus look to you as be just 1 coin?
     
  3. BSacramento

    BSacramento

    Joined:
    Mar 13, 2018
    Posts:
    7
    Yes im sure of that, because sometimes it reads just one coin and other times reads as two coins
     
  4. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Both the Destroy and GetComponent methods are not the most performant. As such, my guess is that there could be some stutter when you touch a coin because you're using both of them twice when that happens. What if instead of destroying those two components, you try disabling them?
    Or better yet, just disable the whole coin game object itself, unless you still want some other components to be enabled when it's touched.

    After that, you could then call the Destroy method, but give it a delay. Something like,
    "Destroy(gameObject, 1f);", which will destroy the coin one second after it's been touched.
     
  5. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,842
    Try adding some debug output to your OnTriggerEnter2D method, something like:

    Code (csharp):
    1. Debug.Log(other.name + " entered " + gameObject.name, gameObject);
    Also, though this is probably unrelated, but why are you destroying the SpriteRenderer and the BoxCollider2D, instead of destroying the whole gameObject?

    (FWIW, I'm not buying the argument that Destroy or GetComponent are causing stutter, or that even if something did cause stutter, it should cause OnTriggerEnter2D to be called twice.)
     
  6. BSacramento

    BSacramento

    Joined:
    Mar 13, 2018
    Posts:
    7
    Destroying components because i did not know that u could destroy the entire object
     
  7. BSacramento

    BSacramento

    Joined:
    Mar 13, 2018
    Posts:
    7
    Also im very new at this, ive no idea how the debug works
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,842
    Copy the line of code I gave you, and paste it into your OnTriggerEnter2D method. Then run, and watch the console. See if it gives you any insight into what's going on in cases where it appears to fire twice.
     
  9. BSacramento

    BSacramento

    Joined:
    Mar 13, 2018
    Posts:
    7
    Yes, everytime i pick up a coin it appears something in the console, if it gives me 1 point it appears "1" inside a circle and when it gives me 2 points it appears "2" in the circle.
     
  10. IronManBK

    IronManBK

    Joined:
    Jul 12, 2017
    Posts:
    7
    @BSacramento sometime your script will call twice and even more, the problem might be unsychonize system timing, you could fix it by adding a new flag ( bool isInscrease ) set it to fail, if on colliding then you set isInscrease = true, and another counter ( int countCall) when colliding happen countCall = 1, and you only increase score if and only if isinscrease = true && countCall = 1, try it, hope it help you out
     
  11. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,842
    Numbers inside a circle?! Can you post a screen shot? (I'm particularly interested in the case where it gives you 2 points.)

    Also, before you do this, please make sure that all your coins have unique names. If the all have the same name, we won't be able to tell what's going on.
     
  12. BSacramento

    BSacramento

    Joined:
    Mar 13, 2018
    Posts:
    7
    There is the print
     

    Attached Files:

  13. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,842
    Oh, I see — you have "Collapse" turned on in your console. I never use that feature, and had forgotten about it. :)

    Aha — I think I see the problem. Some of the objects (at least, the potato object that happened to be selected when you took that screen shot) have multiple colliders. The trigger events may fire twice in one frame if both colliders happen to enter the trigger on that frame.

    So, assuming you really need all those colliders, you'll just have to write your script in such a way that it only gives its award once, no matter how many times the trigger is triggered. One possible way to do that is to call DestroyImmediate(gameObject) in your trigger event, which should destroy the object right away instead of at the end of the frame. I think that will prevent the physics system from invoking it again for the second collider, though I'm not 100% sure.

    So another way is to just put a flag on your script, something like bool paidOut = false;. Then at the top of your trigger method, add

    Code (csharp):
    1. if (paidOut) return;   // already paid out, don't do it again!
    2. paidOut = true;
    That'll prevent it from paying out more than once.
     
  14. BSacramento

    BSacramento

    Joined:
    Mar 13, 2018
    Posts:
    7
    Thank you very much! Problem solved, didnt think the multiple colliders would change that much!
     
    JoeStrout likes this.