En este momento estás viendo Calcule la distancia entre puntos en la matriz conectados en todas las direcciones

 – Unity

Calcule la distancia entre puntos en la matriz conectados en todas las direcciones – Unity

Calcule la distancia entre puntos en la matriz conectados en todas las direcciones

– UnityAssets3Free

hola , me llamo Camilo y aqui os traigo
esta unity pregunta

Estoy tratando de hacer un juego en línea donde quiero simular un mundo conectado en todas las direcciones, como «PAC-MAN». Cuando el jugador cruza los límites del mapa, estará en el otro lado de la cuadrícula.

Hasta ahora todo bien, logré construir un servidor que contiene una matriz de 10×10 (adjunte algunos imágenes como referencia), y utilizando alguna aritmética modular calcula y envía al cliente las piezas correspondientes del mapa según la posición del jugador.

Entonces, asumiendo «view_distance = 2» por ejemplo, el servidor envía las piezas correspondientes según la posición del jugador:

Posición del jugador (4.4)

Posición del jugador (9.5)

Posición del jugador (0.0)

Creo que hice mi punto, ahora enfrentemos mi problema.

Cuando el cliente obtiene la lista de mosaicos para renderizar desde el servidor, necesita calcular la distancia al jugador (vector unitario) para cada mosaico con el fin de instanciar en el lugar correcto. Cada mosaico instanciado tiene un script que vuelve a calcular la distancia al jugador cada vez que se mueve para que se destruya a sí mismo cuando esté más lejos que la «distancia_vista».

Entonces, por ejemplo, si el cliente está en la posición (9,5), el vector unitario del mosaico (7,7) sería (-2,2)

El cliente dispone de la siguiente información:

  • La baldosa en la que está parado: Globals.PlayerInfo.PlayerPosition
  • La longitud del mapa: Globals.MAP_LENGHT (en este caso son 10)
  • La distancia de visualización: Globals.DATA_DISTANCE (en este caso son 2)

¿Cómo calcular el vector unitario? Hice la siguiente función pero no parece funcionar. ¿Me estoy olvidando de algo?

public static Position GetPlayerDistance(Position position)
    
        var unitVector = new Position()  X = position.X, Y = position.Y ;
        if (position.Y > Math.Truncate(Globals.PlayerInfo.PlayerPosition.Y) + Globals.DATA_DISTANCE)
        
            unitVector.Y = position.Y - Globals.MAP_LENGHT;
        

        if (position.X > Math.Truncate(Globals.PlayerInfo.PlayerPosition.X) + Globals.DATA_DISTANCE)
        
            unitVector.X = position.X - Globals.MAP_LENGHT;
        
        unitVector.X -= (float)Math.Truncate(Globals.PlayerInfo.PlayerPosition.X);
        unitVector.Y -= (float)Math.Truncate(Globals.PlayerInfo.PlayerPosition.Y);

        return unitVector;
    

1 respuesta 1

Tú mismo lo dices, la grilla es connected in all directions. Entonces, dado que su cuadrícula es «infinita», cada posición existe un número «infinito» de veces. Lo que estás buscando no es una distancia entre dos puntos, sino la más pequeña de varias posibilidades.

Pero no te preocupes 😉 Basta con marcar una vez en cada dirección (arriba, abajo, izquierda, derecha) y elegir la menor de las distancias resultantes en esas direcciones, ya que cualquier otra será mayor de todos modos.

Solo como un ejemplo de lo que estoy hablando. digamos

  • el jugador esta en 1,1 (rojo)
  • el enemigo esta en 8,2 (azul)

entonces, si queremos obtener la distancia mínima en el eje X, solo verifique en ambas direcciones, izquierda y derecha.

En este caso, encontrar la siguiente posición a la izquierda es trivial: es la posición real del jugador. x = 1.

Ahora que hacemos bien? → Simplemente extendemos virtualmente la cuadrícula (gris claro) y asignamos la posición del jugador a donde haría estar en esta grilla extendida → x = 11 (Luz roja).

Aquí una imagen para que se vea mejor.

En el código, esto podría verse como, por ejemplo

public static Position GetPlayerDistance(Position position)

    // Get values local to not go through the accessors all the time
    Position playerPos = Globals.PlayerInfo.PlayerPosition;
    int playerX = (int)playerPos.X;
    int playerY = (int)playerPos.Y;

    int ownX = (int)position.X;
    int ownY = (int)position.Y;

    // On the X axis gather the next actual or virtual player position
    // where virtual means as if the grid was extended

    // Per default assume the positions are equal  
    var nextXLeft = ownX;
    var nextXRight = ownX;

    // Is the player actually left of us?
    if(playerX < ownX)
    
        // Then trivial: the next left position is the actual one
        nextXLeft = playerX;
        // The next right position is a virtual one so we pretend
        // to extend the grid by the length and "copy" the player there
        nextXRight = Globals.MAP_LENGHT + playerX;
     
    // Or is the player actually right of us?
    else if (playerX > ownX)
    
        // Just the other way round
        // this time the next position to the left is virtual
        nextXLeft = -Globals.MAP_LENGHT + playerX;
        // The next right position is the actual one
        nextXRight = playerX;
    

    // Now we calculate the directed distances in both directions
    var distanceLeft = nextXLeft - ownX;
    var distanceRight = nextXRight - ownX;

    // use the Absolute only for comparing which is shorter
    var distanceX = Mathf.Abs(distanceRight) < Mathf.Abs(distanceLeft) ? distanceRight : distanceLeft;

    // And finally we want the smallest of both possible distances
    var distanceX = Mathf.Min(distanceLeft, distanceRight);

    // Repeat the same for the Y axis
    var nextYDown = ownY;
    var nextYUp = ownY;
    if(playerY < ownY)
    
        nextYDown = playerY;
        nextYUp = Globals.MAP_LENGHT + playerY;
     
    else if (playerY > ownY)
    
        nextYDown = -Globals.MAP_LENGHT + playerY;
        nextYUp = playerY;
    

    var distanceDown = nextYDown - ownY;
    var distanceUp = nextYUp - ownY;

    var distanceY = Mathf.Abs(distanceUp) < Mathf.Abs(distanceDown) ? distanceUp : distanceDown;

    // Now you have a directed distance vector for both axis with the 
    // minimal absolute distance from the player
    return new Position() X = distanceX, Y = distanceY ;

Aquí hay una pequeña vista previa de cómo funciona ahora

Como nota al margen: ya existe Vector2Int es posible que desee utilizar en lugar de su habitual Position

nota: si aun no se resuelve tu pregunta por favor dejar un comentario y pronto lo podremos de nuevo , muchas gracias

eso es todo,espero que te halla servido

Deja una respuesta