En este momento estás viendo Mover la cámara a la posición correcta en la función Zoom en Unity

 – Unity

Mover la cámara a la posición correcta en la función Zoom en Unity – Unity

Mover la cámara a la posición correcta en la función Zoom en Unity

– UnityAssets3Free

hola , soy juansito y hoy os traigo
nueva pregunta

Hola, tengo una duda que espero que alguien me pueda ayudar a resolver. Pregunté en otros lugares sin éxito, pero parece un problema estándar, así que no estoy seguro de por qué no obtengo respuestas.

Básicamente está configurando una función de zoom que refleja el zoom de Google Maps. Por ejemplo, la cámara acerca o aleja el zoom hacia donde está el mouse. Sé que esto probablemente se pregunte mucho, pero creo que el nuevo sistema de entrada de Unity ha cambiado un poco las cosas con respecto a las preguntas de 4 a 6 años que encontré en mi propia investigación.

De todos modos, configuré un GameObject principal que contiene todos los sprites 2D que estarán en mi escena y una cámara ortográfica. Puedo configurar el tamaño ortográfico a través del código para cambiar al zoom, pero está moviendo la cámara a la ubicación correcta con la que tengo problemas.

Este fue mi primer intento:

public Zoom(float direction, Vector2 mousePosition) 
    // zoom calcs
    float rate 1 + direction * Time.deltaTime;
    float targetOrtho = Mathf.MoveTowards(mainCam.orthographicSize, mainCam.orthoGraphicSize/rate, 0.1f);

    // move calcs
    mousePosition = mainCam.ScreenToWorldPoint(mousePosition);
    Vector2 deltaPosition = previousPosition - mousePosition;
    
    // move and zoom    
    transform.position += new Vector3(deltaPosition.x, deltaPosition.y, 0);
    // zoomLevels are a generic struct that holds the max/min values.
    SetZoomLevel(Mathf.Clamp(targetOrthoSize, zoomLevels.min, zoomLevels.max));

    previousPosition = mousePosition;

Esta función se llama a través de mi controlador de entrada, activado a través de los eventos del sistema de entrada de Unity. Cuando la rueda del mouse se desplaza, la función Zoom recibe un valor normalizado como direction (1 o -1) y la corriente mousePosition. Cuando termine su cálculo, la posición del mouse se almacena en previousPosition.

El código realmente funciona, excepto que es extremadamente inestable. Esto, por supuesto, se debe a que no hay Time.deltaTime aplicado al movimiento de cámara, ni siquiera eso está en LateUpdate; ambos ayudan a suavizar los movimientos. Excepto, en el primer caso, multiplicando Time.deltaTime por new Vector3(deltaPosition.x, deltaPosition.y, 0) parece hacer que se acerque al centro de la cámara en lugar de la posición del mouse. cuando hago zoom LateUpdatecrea un efecto de movimiento agradable pero no deseado cuando la cámara se mueve.

Entonces, después de pensar y leer un poco, pensé que sería mejor calcular la diferencia entre la posición del mouse y el punto central de la cámara y luego multiplicarla por un factor de escala, que es el tamaño ortográfico de la cámara * 2 (quizás… ?? ). De ahí mi código actualizado aquí:


    public void Zoom(float direction, Vector2 mousePosition)
    
        // zoom
        float rate = 1 + direction * Time.unscaledDeltaTime * zoomSpeed;
        float orthoTarget = Mathf.MoveTowards(mainCam.orthographicSize, mainCam.orthographicSize * rate, maxZoomDelta);
    
        SetZoomLevel(Mathf.Clamp(orthoTarget, zoomLevels.min, zoomLevels.max));
    
        // movement
        if (mainCam.orthographicSize < zoomLevels.max && mainCam.orthographicSize > zoomLevels.min)
        
            mousePosition = mainCam.ScreenToWorldPoint(mousePosition);
            Vector2 offset = (mousePosition - new Vector2(transform.position.x, transform.position.y)) / (mainCam.orthographicSize * 2);
    
            // panPositions are the same generic struct holding min/max values
            offset.x = Mathf.Clamp(offset.x, panPositions.min.x, panPositions.max.x);
            offset.y = Mathf.Clamp(offset.y, panPositions.min.y, panPositions.max.y);
    
            transform.position += new Vector3(offset.x, offset.y, 0) * Time.deltaTime;
        
     

Esto parece un poco más cercano a lo que estoy tratando de lograr, pero la cámara aún se acerca a su punto central y se aleja en algún punto… Estoy un poco perdido en cuanto a lo que me estoy perdiendo aquí.

¿Alguien puede ayudarme a guiar mi pensamiento sobre lo que debo hacer para crear un zoom suave en el punto donde se encuentra actualmente el mouse? Muy apreciado y gracias por leer esto.

1 respuesta 1

Bien, me di cuenta de esto en caso de que alguien más haya tenido el mismo problema. es un problema estándar que se resuelve fácilmente una vez que conoces las matemáticas.

Básicamente, se trata de escalar y trasladar la cámara. Puedes hacer una o la otra primero, no importa; El resultado es el mismo. Imagina que tu pantalla se ve así:

El cuadro verde es la ventana de vista previa de la cámara, la flecha es el cursor. Cuando hace zoom, el tamaño ortográfico se vuelve más pequeño y se encoge alrededor de su punto de anclaje (normalmente P1(0,0)). Este es el aspecto de escala del problema y la siguiente imagen lo explica bien:

Así que ahora queremos mover la posición de la cámara a la nueva posición:

¿Entonces como hacemos esto? Solo es cuestión de obtener la distancia desde la posición anterior de la cámara (P1(0, 0)) hasta la nueva posición de la cámara (P2(x,y)). Básicamente, solo queremos esto:

Mi solución para encontrar la longitud de la flecha en la imagen de arriba fue básicamente restar la longitud de la posición del cursor de la posición anterior de la cámara (oldLength) desde la longitud de la posición del cursor hasta la nueva posición de la cámara (newLength).

pero como encuentras newLength? Bueno, como sabemos que la longitud se escalará según el tamaño de la ventana de la cámara, newLength será cualquiera oldLength / scaleFactor o oldLength * scaleFactor, dependiendo de si desea acercar o alejar, respectivamente. El factor de escala puede ser el que quieras (ampliar/reducir en 2, 4, 1,4… lo que sea).

A partir de ahí, solo resta newLength desde oldLength y agregando esta diferencia desde la posición actual de la cámara. El pseudocódigo está a continuación:

(Tenga en cuenta que cambié ‘newLength’ a ‘length’ y ‘oldLength’ a ‘scaledLength’)

// make sure you're working in world space
mousePosition = camera.ScreenToWorldPoint(mousePosition);

length = mousePosition - currentCameraPosition;
scaledLength = length / scaleFactor // to zoom in, otherwise its length * scaleFactor
deltaLength = length - scaledLength;

// change position
cameraPosition = currentCameraPosition - deltaLength;
// do zoom
camera.orthographicSize /= scaleFactor  // to zoom in, otherwise orthographic size *= scaleFactor

Funciona perfectamente para mí. ¡Gracias a todos los que me ayudaron en una comUnity de codificación de discordia!

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

eso es todo,hasta la proxima

Deja una respuesta