- Home /
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);
}
}
}
}
Answer by swanne · Oct 18, 2021 at 03:28 PM
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.
Hi Swanne,
thank you for your answer. The issue is related to Unity conversion between Quaternions and the EulerAngles shown in the inspector. Basically it gives me the usual 90.0001 value that does not go well with the == operator. I've tried Mathf.Approximately, but it still gave me issues.
I''m leaning towards your approach for the rotations check, normalising and having a bit of leeway.
Right now I've put a simple patch that seems to work:
if (this.transform.localEulerAngles.z > 90 && this.transform.localEulerAngles.z < 180)
{
transform.rotation = Quaternion.Euler(0, 0, 90);
}
It converts the value to a fixed 90 when it's true in the start and rotation method. This way the bug seems fixed (even if it's probaly not the best way to address this).
Regarding the Array to List conversion is something I'm considering to achieve better comparisons and simplify removal of objects from the list.
Thank you again for you time, have a nice day!
You are most welcome :)
Good luck with your game!
Your answer
Follow this Question
Related Questions
Trouble - Limit rotation on Z-axis 0 Answers
[2D] Player's arm following the mouse 1 Answer
How do I make an angle with the X axis, Y axis, and Z axis and not rotate AROUND the axis? 0 Answers
I'm having trouble clamping the rotation of the camera? 0 Answers
Calculate rotation angle for two side of cube ( like dice ) from Quaternion.identity 0 Answers