Game goes to GameOver when act is done

Hey, I have a simple swipe game - when there is right arrow displayed, the user should swipe right (and also for other directions). This is my code (it`s just repeating itself so I will post only one direction):

if (left && frameCounterLeft <= maxFrames && isLeftNow)
        {
            //Reset the other directions
            right = false;
            up = false;
            down = false;
            tap = false;

            //First time
            if (frameCounterLeft == 0)
                ThrowLeft(true);
            else
                ThrowLeft(false);

            //Animation
            frameCounterLeft++;

            //End animation
            if (frameCounterLeft == maxFrames)
            {
                ClonePlayer();
                frameCounterLeft = 0;
                left = false;
               
            }
        }
        else if (left && frameCounterLeft == 0 && !isLeftNow)
        {
            GameOver();
        }

left/right/up/down = user input left/right/up/down swipe - working (checked)
tap = if user taps the screen - working (checked)
framesCounterLeft = for the animation to be couple frames
isLeftNow = if the left arrow is displayed right now - working (checked)

GameOver() is called when I am doing any swipe (even if it`s a right swipe).
e.g - There is left arrow displayed. When I swipe left (or any other direction) GameOver() is called.

Please help me I want to continue developing this game.

Well it must mean that isLeftNow is false and frameCounterLeft is zero. What does this say:

                Debug.Log(left);
                Debug.Log(frameCounterLeft);
                Debug.Log(maxFrames);
                Debug.Log(isLeftNow);
                if (left && frameCounterLeft <= maxFrames && isLeftNow)
                {
                                       //Reset the other directions
                    right = false;
                    up = false;
                    down = false;
                    tap = false;

                    //First time
                    if (frameCounterLeft == 0)
                        ThrowLeft(true);
                    else
                        ThrowLeft(false);

                    //Animation
                    frameCounterLeft++;

                    //End animation
                    if (frameCounterLeft == maxFrames)
                    {
                        ClonePlayer();
                        frameCounterLeft = 0;
                        left = false;

                    }
                }
                else if (left && frameCounterLeft == 0 && !isLeftNow)
                {
                    GameOver();
                }

We don’t have any more context on what isLeftNow is or where maxFrames is set. So you need to check those two places. I suspect there could be an execution race, or something that sets/resets maxFrames/isLeftNow is not being called correctly.

Thanks for answer.
maxFrames is set in the beggining of the code and not changing at all. isLeftNow changes in the function ClonePlayer(). Basically, when a new card is being instantiated isLeftNow is getting true if the card is left and false if its on any other direction. Will it be helpful if I post the ClonePlayer() method?

That would give a bit more context. Looking at this in more thought. I think it must be isLeftNow.

For this to fail:

if (left && frameCounterLeft <= maxFrames && isLeftNow)

either left doesn’t exist, which it must for the next else if to pass, maxFrames is less than frameCounterLeft (which would mean maxFrames would need to be a value less than zero for the next else if to pass), or isLeftNow must be false. Looking at that breakdown of logic it looks like isLeftNow is false. That would cause it to move to the else if statement and still be on the first counter (frameCounterLeft would still be zero) for it to pass and hit GameOver(). That’s my prediction. Ensure isLeftNow is correct at the point of hitting the if statement block.

Got you, but I need to figure out why isLeftNow is corrent and how to ensure it. There is the method:

void ClonePlayer()
    {
        //Destroy last card:
        GameObject newPlayer = Object.Instantiate(player, Vector3.zero, new Quaternion());
        Destroy(player);

        //assign the new player to existing one:
        player = newPlayer;

        //give the texture:
        #region 4 directions
        if (score < whenToDisplayBombs)
        {
            //decide which direction:
            cardDirection = Random.Range(1, 5);
            if (cardDirection == 1)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Left;
                isLeftNow = true;
                isRightNow = false;
                isUpNow = false;
                isDownNow = false;
            }
            if (cardDirection == 2)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Right;
                isLeftNow = false;
                isRightNow = true;
                isUpNow = false;
                isDownNow = false;
            }
            if (cardDirection == 3)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Up;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = true;
                isDownNow = false;
            }
            if (cardDirection == 4)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Down;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = false;
                isDownNow = true;
            }
        }
        #endregion
        #region 4 directions + bombs
        else if (score >= whenToDisplayBombs && score < whenToDisplayOppositeDirections)
        {
            //Deploy obstacles: bombs
            cardDirection = Random.Range(1, 10);
            if (cardDirection == 1 || cardDirection == 2)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Left;
                isLeftNow = true;
                isRightNow = false;
                isUpNow = false;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 3 || cardDirection == 4)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Right;
                isLeftNow = false;
                isRightNow = true;
                isUpNow = false;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 5 || cardDirection == 6)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Up;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = true;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 7 || cardDirection == 8)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Down;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = false;
                isDownNow = true;
                isBombNow = false;
            }
            if (cardDirection == 9)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Bomb;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = false;
                isDownNow = false;
                isBombNow = true;
            }
        }
        #endregion
        #region 4 directions + bombs + opposite directions
        else
        {
            //Deploy obstacles: opposite directions
            cardDirection = Random.Range(1, 14);
            if (cardDirection == 1 || cardDirection == 2)
            {
                //Left
                player.GetComponent<SpriteRenderer>().sprite = card_Left;
                isLeftNow = true;
                isRightNow = false;
                isUpNow = false;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 3 || cardDirection == 4)
            {
                //Right
                player.GetComponent<SpriteRenderer>().sprite = card_Right;
                isLeftNow = false;
                isRightNow = true;
                isUpNow = false;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 5 || cardDirection == 6)
            {
                //Up
                player.GetComponent<SpriteRenderer>().sprite = card_Up;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = true;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 7 || cardDirection == 8)
            {
                //Down
                player.GetComponent<SpriteRenderer>().sprite = card_Down;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = false;
                isDownNow = true;
                isBombNow = false;
            }
            if (cardDirection == 9)
            {
                player.GetComponent<SpriteRenderer>().sprite = card_Bomb;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = false;
                isDownNow = false;
                isBombNow = true;
            }
            if (cardDirection == 10)
            {
                //Opposite left
                player.GetComponent<SpriteRenderer>().sprite = card_Opposite_Left;
                isLeftNow = false;
                isRightNow = true;
                isUpNow = false;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 11)
            {
                //Opposite right
                player.GetComponent<SpriteRenderer>().sprite = card_Opposite_Right;
                isLeftNow = true;
                isRightNow = false;
                isUpNow = false;
                isDownNow = false;
                isBombNow = false;
            }
            if (cardDirection == 12)
            {
                //Opposite up
                player.GetComponent<SpriteRenderer>().sprite = card_Opposite_Up;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = false;
                isDownNow = true;
                isBombNow = false;
            }
            if (cardDirection == 13)
            {
                //Opposite down
                player.GetComponent<SpriteRenderer>().sprite = card_Opposite_Down;
                isLeftNow = false;
                isRightNow = false;
                isUpNow = true;
                isDownNow = false;
                isBombNow = false;
            }
        }
        #endregion
    }

It’s gonna be so hard to debug something written that way, no wonder you’re struggling. It might be an idea to remove all those booleans and replace them with a single enum. Something like:

public enum Direction { Left, Up, Right, Down }
        public Direction currentDirection = Direction.Up;
       
        void ExampleUseDirections()
        {
            if(currentDirection == Direction.Up)
            {
                currentDirection = Direction.Down;
            }
        }

That way you know it will only be going one direction at a time and will be a lot easier to read. Once you’ve done that it’ll be clearer to see what’s going on. Asides that Debug.Log’s and breakpoints are your friend. It might be an idea to write some test code that forces a particular response, and make sure that works. Like for example just make a method that forces cardDirection to be 12 always, and start working from that assumption.

So you say replace the isLeftNow with enum of left with enum or both
UPDATE
I have converted left/right/up/down to enum but now the input isn`t working… its like this:

if (swipeControls.GetSwipeLeft())
            dir = Direction.Left;
        if (swipeControls.GetSwipeRight())
            dir = Direction.Right;
        if (swipeControls.GetSwipeUp())
            dir = Direction.Up;
        if (swipeControls.GetSwipeDown())
            dir = Direction.Down;
        if (swipeControls.GetSwipeTap())
            dir = Direction.Tap;
        else
            dir = Direction.None;

It worked before with the bool and now the only one that works is the tap and none.

Okay, so the directions aren’t working now. Can you post the GetSwipe’SomeDirection’ method?

Never mind, It is all working prefect now, Thanks man you helped me alot!!
Just one more question: how can I identify if the player is clicking the screen (short click) or tapping it (for android - short tap as well)

1 Like

How are you checking for input right now? Are you aiming for multiple platforms?

only for windows and android - currently windows… The problem is I can identify only short vector (the vector is the mouse when mouse button is up - the mouse when mouse button is down) and not a click in place…

You’ll want a way to classify a short tap. You’ll also want to use a different system each for Windows and Android. This is untested, but something like this:

        [SerializeField, Range(000.1f, 1f)] private float tapTimer;
        private float tapDownTime;

        private void Update()
        {
            if(Application.platform == RuntimePlatform.Android)
            {
                CheckAndroidTap();
            }
            else
            {
                CheckWindowsClick();
            }
        }
       
        private void CheckWindowsClick()
        {
            if (Input.GetMouseButtonDown(0))
            {
                tapDownTime = Time.timeSinceLevelLoad;
            }
            if (Input.GetMouseButtonUp(0))
            {
                if ((Time.timeSinceLevelLoad - tapDownTime) < tapTimer)
                {
                    // Do the tap
                }
            }
        }

        private void CheckAndroidTap()
        {
            if(Input.touchCount > 0)
            {
                if (Input.GetTouch(0).phase == TouchPhase.Began)
                {
                    tapDownTime = Time.timeSinceLevelLoad;
                }
                else if (Input.GetTouch(0).phase == TouchPhase.Ended)
                {
                    if ((Time.timeSinceLevelLoad - tapDownTime) < tapTimer)
                    {
                        // Do the tap
                    }
                }
            }
        }

Thanks!