Last collision

Hi.

I’m doing a spinner and i want to detect the last slot the needle touch, because i need to launch an event after the spinner stops.

    void OnTriggerStay2D(Collider2D col)
    {
        if (!_spinner.isStoped)
            return;

        if (col.gameObject.tag == ("1")) SpinPosition = 1;
        if (col.gameObject.tag == ("2")) SpinPosition = 2;
        if (col.gameObject.tag == ("3")) SpinPosition = 3;
        if (col.gameObject.tag == ("4")) SpinPosition = 4;
        if (col.gameObject.tag == ("5")) SpinPosition = 5;
        if (col.gameObject.tag == ("6")) SpinPosition = 6;
        if (col.gameObject.tag == ("7")) SpinPosition = 7;
        

    }

    void SpinCheck ()
    {
        switch (SpinPosition)
        {
            case 1:
                    Debug.Log("Slot 1");
                break;
            case 2:
                    Debug.Log("Slot 2");
                break;
            case 3:
                Debug.Log("Slot 3");
                break;
            case 4:
                Debug.Log("Slot 4");
                break;
            case 5:
                Debug.Log("Slot 5");
                break;
            case 6:
                Debug.Log("Slot 6");
                break;
            case 7:
                Debug.Log("Slot 7");     
                break;

        }

    }

So, the thing is that, debug log keeps printing the event like this: alt text

i ned it to be called just once.

OnTriggerStay is called for every frame that an object is within the trigger, so the log will print continuously.

What you should do is set SpinPosition on OnTriggerEnter, and remove the
if (!_spinner.isStoped) return;

part. Now, I’m not quite sure how exactly you are setting _spinner.isStoped, but I’m assuming it’s set to true when the velocity is low enough, and isn’t set again until the spinner is spun again, where you would set it to true.
Something like:

if(!isStopped && velocity<threshold){
     velocity = 0;
     isStopped = true;
}

I imagine?

If there’s a difference in how this works, the important bit to note is that this only gets called once. When isStopped is true, it doesn’t enter the if statement again. Well if it resembles this form at all, the change is simply to:

if(!isStopped && velocity<threshold){
      velocity = 0;
      isStopped = true;
      SpinCheck(); //Check what it's on only when it stops
 }

Thus:

SpinCheck() is only called once per stop

SpinPosition is only set when it changes

You can fire your event without problems.


On a slightly unrelated note, consider the fact that frankly the physics engine is a bit overkill for something like a spinner, and juggling tags and colliders can end up getting messy over time, as well as feel rather floaty and dull without some serious extra work put into it. You also lose the ability to set probabilities explicitly, which can make balancing the outcomes of those spinners quite difficult. The physics engine won’t make the outcome that much more random or unpredictable either, and frankly it often doesn’t matter. A human player will still see randomness even when the RNG used is not actually random (take XorShift for example), and most certainly won’t be able to predict the results.

I would recommend you simply make your spinner start spinning really fast, calculate an RNG probability, and then snap to that part of the spinner and continue to spin a certain number of rotations, slowing down as it goes, before doing some easing to make the spinner appear to come to a gentle stop or snap into place.

The fact is, in reality, most spinners in videogames tend to know exactly what they will land on before they even start spinning. This means that they can be run for specific probabilities, making game rules more explicit, as well as preventing players from being able to skip past them, as the spinner itself is just a pretty face for the outcome that has been already been determined.

Using the physics engine has no real benefit here, and I would advise writing the spinner’s behaviour explicitly. The result will be easier for you to control, and not prone to annoying ‘feels wrong’ moments. My team and I call this “Mechanic like you mean it” and I would consider this a good design trait.