Jump to content
UnitySpain
Sign in to follow this  
arganthammer

Simplificación del foreach...

Recommended Posts

Hola a todos. Estoy haciendo un juego 2D y soy nuevo en esto. Quería saber si hay alguna forma de comparar dentro de un if, la posición de un bloque con una etiqueta, con la posición de otro bloque con otra etiqueta, sin tener que recurrir a meter como lo estoy haciendo un foreach (gameObject x in x) dentro de otro por cada etiqueta y luego comparar posiciones. (Los guardo con un FindGameObjectWithTag). Como tengo muchos bloques con cada etiqueta, tiene que hacer más de mil comparaciones. También le pongo un break si se da la comparación, pero cuando hay que hacer esto y hay muchos bloques apilados que necesitan ser comparados con la posición de algún bloque del suelo se vuelve costoso, además que como se han de mover esos bloques, no puedo hacerlo en el momento en el que se da la comparación, porque se moverían uno tras otro y no a la vez. Pregunto si hay alguna forma de hacer estas comparaciones entre etiquetas de una forma más simple. Y perdonen mi torpeza.

Share this post


Link to post
Share on other sites

Lo mejor sería que subas el código así se ve más claro lo que estás intentando hacer, pero bueno, si querés comparar dos etiquetas vas a tener que referenciar dos strings por sus valores y ver si son iguales, eso seguro. Quizás el truco está en no considerar a los n objetos sino a una parte, no se cual es el criterio que estás usando para esto, pero si por ej quisieras comparar objetos cercanos podrías obtenerlos mediante distancias y luego realizar la comparación de strings, otra sería tenerlos definidos en un array y verificar las strings de los vecinos. A lo que voy es que si querés comparar todas las etiquetas sin ningún criterio previo se vuelve así de simple, recorrer todos y ver si son iguales. Un algoritmo básico de comparación podría ser (genérico para "Obj" de un contenedor):

for( int i = 0 ; i < contenedor.Count - 1 ; i++ )
{
  	Obj objA = contenedor[ i ];
	for( int j = i + 1 ; j < contenedor.Count ; j++ )
    {
      	Obj objB = contenedor[ j ];
    	if( objA == objB )
        {
        	// acción ...          	
        }  	
        
    }
      
}

Te parás en el "i" e iterás sobre el resto (> i), cada vez que i aumenta (primer for) se va acortando el ciclo cada vez más, en "// acción" podés setear algun flag que haga de condición de salida, o sino usar un while (creo que es más conveniente):

int i = 0;
int j = 0;

bool listo = false;
while( listo )
{	
  	Obj objA = contenedor[ i ];
	for( int j = i + 1 ; j < contenedor.Count ; j++ )
    {
      	Obj objB = contenedor[ j ];
    	if( objA == objB )
        {
          	listo = true;
        	// acción ...          	
        }  	
        
    }
	
  	i++;
  	
  	if( i == contenedor.Count - 1 )
    	listo = true;      	
                                     
      
}

Creo que no la pifié, lo hice acá asi que no confies al 100%.

El "for" siempre es preferido frente al "foreach", el proceso del Loop interno es más simple y hace lo mismo (adem´sa de darte la posibilidad de saber el índice actual). El foreach es más lento, ahora, dependerá de cuan lento sea frente a todo el proceso general, si todo se realiza en 1us vs 5us es básicamente lo mismo, si el foreach te queda más comodo está barbaro usarlo, ahora si la tarea involucra GameObjects o Transform o clases de otro tipo, es preferible el for.

Ah, y las comparaciones de etiquetas se  realiza por valor usando "CompareTag":

https://docs.unity3d.com/ScriptReference/Component.CompareTag.html

 

Share this post


Link to post
Share on other sites

Con los iEnumerator (p.ej. list) puedes hacer grupos con las extensiones de Find y FindAll para no tener que comparar en las iteraciones. Si quieres algo más avanzado y que puedas utilizarlo para cualquier grupo de datos tienes las extensiones de Linq (System.Linq).

Share this post


Link to post
Share on other sites
Sign in to follow this  

×