I’m having issues with my code. I’m trying to convert an vector2 to an array index. I do this through getting the float values of the vector2. By doing transform.position.x and y. Then inputting it into a function that goes to an integer value. The error is in here I think. Take note: uploading the entire script is too large and not well ordered. I upload this piece because this is the important part.This is an monobehaviour that is using UnityEngine, System.Collections and System.Collections.generic.
The error is on line 10. Combined with the functions down below.
void MainPathRoomGenerator()
{
randomNumber2 = Random.Range(0, 3);
switch (randomNumber2)
{
case 0:
pathPlacer.transform.position = new Vector2(pathPlacer.transform.position.x - 3.52f, pathPlacer.transform.position.y);
dungeonRooms[getDungeonRoomArrayLocationX(pathPlacer.transform.position.x), getDungeonRoomArrayLocationY(pathPlacer.transform.position.y)] = Instantiate(rooms[0], new Vector2(pathPlacer.transform.position.x, pathPlacer.transform.position.y), Quaternion.identity, parent);
break;
case 1:
pathPlacer.transform.position = new Vector2(pathPlacer.transform.position.x + 3.52f, pathPlacer.transform.position.y);
break;
case 2:
pathPlacer.transform.position = new Vector2(pathPlacer.transform.position.x, pathPlacer.transform.position.y - 3.52f);
break;
}
}
float getDungeonRoomArrayLocationX(float x)
{
if(x == 0.0f)
xRoom = 0;
if (x == 3.52f)
xRoom = 1;
if (x == 7.04f)
xRoom = 2;
if (x == 10.56f)
xRoom = 3;
if (x == 14.08f)
xRoom = 4;
return xRoom;
}
float getDungeonRoomArrayLocationY(float y)
{
if (y == 0.0f)
yRoom = 0;
if (y == 3.52f)
yRoom = 1;
if (y == 7.04f)
yRoom = 2;
if(y == 10.56f)
yRoom = 3;
if (y == 14.08f)
yRoom = 4;
return yRoom;
}
you should probably make your ‘getDungeonRoomArrayLocatoinX’ return an ‘int’ not a ‘float’. Seeing as xRoom and yRoom are whole values… since they’re indices… and indices for an array are ints.
Also… I’m going to point ou tthat float error is going to make it really hard to perfectly equal values like ‘3.52’ and ‘7.04’. What are the odds the position is going to be EXACTLY that?
Ah, yes. Thank you for your help! I will try to solve my issue with your help soon. But, the reason why I’m sure the positions are EXACTLY that. Is because I’m making an procedural dungeon generation system. Every room is exactly 3.52 units wide and high. So, if I place a room behind a room. I get the values 3.52 and 7.04. So, I’m 100% sure that the values will always be right. Do you understand?
And the value 3.52, and multiples of it, can drift from their actual value. the 2/100 portion of that fraction pretty much guarantees that in binary it’s a repeating digit (like how 1/3 is repeating in decimal). But since memory can only hold a finite number of digits, it gets lopt off.
This is why sometimes you’ll see floats with values like 7.000001, and the sort. It’s the result of floating point error.
As a result it’s considered a bit ‘eh’ to rely on floats being accurate. Usually you come up with some other way to identify the thing, or in the moments when you REALL REALLY need to compare floats, no way around it, people use ‘Fuzzy’ logic. Like this:
public const float EPSILON = 0.0001f;
/// <summary>
/// Test if float is kind of equal to some other value by some epsilon.
///
/// Due to float error, two values may be considered similar... but the computer considers them different.
/// By using some epsilon (degree of error) one can test if the two values are similar.
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <param name="epsilon"></param>
/// <returns></returns>
/// <remarks></remarks>
public static bool FuzzyEqual(float a, float b, float epsilon)
{
return Math.Abs(a - b) < epsilon;
}
public static bool FuzzyEqual(float a, float b)
{
return FuzzyEqual(a, b, EPSILON);
}
Thank you, I’m working with small values. I repeat this process 5 times. 5 times 3.52, will that be a real problem? So, I looked at my code to see if I return integer values. I do return those. This is my variable code. The beginnining of the script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DungeonGeneratorStart : MonoBehaviour
{
public int room_width = 10;
public int room_height = 10;
public GameObject[] rooms;
public GameObject[] endRooms;
public GameObject startRoom, pathPlacer;
public Transform parent;
private bool beginRoom;
private int enterancePos, randomNumber, randomNumber2;
private int xRoom, yRoom;
You can see the variables are integer. I don’t understand why I get that error. Is it because of the way how computer handle floats? The way how you just explained me?
dungeonRooms is an array, it expects ints as the index, getDungeonRoomArrayLocationX (and Y) return floats. Don’t do that, return an int.
//note I changed it to int, not float
int getDungeonRoomArrayLocationX(float x)
{
if(x == 0.0f)
xRoom = 0;
if (x == 3.52f)
xRoom = 1;
if (x == 7.04f)
xRoom = 2;
if (x == 10.56f)
xRoom = 3;
if (x == 14.08f)
xRoom = 4;
return xRoom;
}
Also… why is xRoom a field if all it’s used for is to be returned by this method? You can scope that locally. Are you saving the value as a class level field for historical posterity or something? So you can see what the index was the last time the method was called or something?
Or… which I see people do this… you believe this is some memory/speed saving attempt. Because it’s not.