How to compare rotation position with an Int value (2D game)

Hello everyone,

I’m developing a series of minigames for a project, and one of them is the classic water pipe one: rotate the pipes in the correct position, water will flow, yadda yadda. The games are developed using a 2D enviroment.


The overall structure of the minigame is working correctly: each pipe get spawned at a random fixed angle degree on the z axis (0, 90, 180, 270) and when the player interact with it it can rotate the object by 90 degress each time (I’m using transform.rotation *= Quaternion.Euler). This works fine as the pipes rotate correctly.


Each pipe have an int array that, depending on the type of pipe, holds 1 or more correct angle position (I.E.: a straight pipe is positioned correctly either with a value of 0 or 180).

To define if a pipe is positioned correctly or not, I make a direct comparison between the localEulerAngles and the int array value. If the value matches, then the pipe is positioned correctly, and gets added to the number of correct pipes (this holds the number of correctly placed pipes and if its equals to the number of interactable pipes, the minigame ends).


Now, to the issue: the comparison between the two values have been quite erratic, as sometimes it works, sometimes not. Sometimes work for just one of the correct values the pipe has (I.E.: is marked as correctly placed when the value is 0, but not when 180 and viceversa), sometimes for neither of them.
When a pipe does not work, I’ve found that by manipulating the rotation value on the inspector during runtime helps in achieving the goal, as it’s resetting the value to a whole number.

Here’s the code governing the pipes, nothing else happens outside of this script other than a MinigameManager that keeps track of the pipes placed correctly.

My question is: there are better ways to make a comparison between a rotation value and an Integer?


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ui_Minigame_Electricity_Button_Behaviour : MonoBehaviour
{

    [SerializeField]
    int[] correctRotation;

    public bool isInCorrectPosition = false;

    int[] pieceRotations = {90, 180, 270};
    int randomRotation;
    int possibleRotations;
    GameObject button;

    ui_Minigame_Water_GameManager ui_Minigame_Manager;

    private void Start()
    {
        button = this.gameObject;
        ui_Minigame_Manager = FindObjectOfType<ui_Minigame_Water_GameManager>();
        randomRotation = Random.Range(0, pieceRotations.Length);
        button.GetComponent<Button>().transform.rotation = Quaternion.Euler(0, 0, pieceRotations[randomRotation]);
        possibleRotations = correctRotation.Length;

        if (possibleRotations > 1)
        {
            if (transform.eulerAngles.z.Equals(correctRotation[0]) || transform.eulerAngles.z.Equals(correctRotation[1]))
            {
                isInCorrectPosition = true;
                ui_Minigame_Manager.CorrectPipePosition();
                Debug.Log(gameObject.name + " ha una rotazione di " + transform.eulerAngles.z);
            }
        }
        else
        {
            if (transform.eulerAngles.z.Equals(correctRotation[0]))
            {
                isInCorrectPosition = true;
                ui_Minigame_Manager.CorrectPipePosition();
                Debug.Log(gameObject.name + " ha una rotazione di " + transform.rotation.z);
            }
        }
    }

    public void Rotation()
    {
        button.GetComponent<Button>().transform.rotation *= Quaternion.Euler(0, 0, 90);

        if (possibleRotations > 1)
        {
            if (transform.localEulerAngles.z.Equals(correctRotation[0]) || transform.localEulerAngles.z.Equals(correctRotation[1]) && !isInCorrectPosition)
            {
                isInCorrectPosition = true;
                ui_Minigame_Manager.CorrectPipePosition();
                Debug.Log(gameObject.name + " ha una rotazione di " + transform.localEulerAngles.z);
            }
            else if (isInCorrectPosition)
            {
                isInCorrectPosition = false;
                ui_Minigame_Manager.IncorrectPipePosition();
                Debug.Log(gameObject.name + " ha una rotazione di " + transform.localEulerAngles.z);
            }
        }
        else
        {
            if (transform.localEulerAngles.z.Equals(correctRotation[0]) && !isInCorrectPosition)
            {
                isInCorrectPosition = true;
                ui_Minigame_Manager.CorrectPipePosition();
                Debug.Log(gameObject.name + " ha una rotazione di " + transform.localEulerAngles.z);
            }
            else if (isInCorrectPosition)
            {
                isInCorrectPosition = false;
                ui_Minigame_Manager.IncorrectPipePosition();
                Debug.Log(gameObject.name + " ha una rotazione di " + transform.localEulerAngles.z);
            }
        }
    }
}

1 Answer

1

Hi,

Fantastic description!

Without having a working project to test against I can only make suggestions of things I would consider.

I prefer using List instead of array. Then you could use the comparison of if list.contains(values) which I find works nicer than multiple || comparisons.

I would also test the effect of normalising your rotations to achieve a rounded value, and also build in a tolerance when comparing the values - eg, 90 = 88 - 92, 180 = 178 - 182.