Unity2D implementa la rueda del mouse de desplazamiento UGUI para hacer zoom en la imagen centrada en el punto de posición del mouse

 Pongamos primero el artículo de referencia:

Unity3d UGUI escala las imágenes centradas en la posición del mouse (incluido el código fuente del proyecto) https://blog.csdn.net/qq_33789001/article/details/117749837

Luego ponlo para lograr el efecto:


Hablemos de la razón. El proyecto necesitaba usar este efecto, así que encontré un artículo de referencia en línea. Más tarde, no sabía por qué no funcionaba, así que pensé en cambiarlo yo mismo para ver cuál era el problema.

Publica el código original:

    //ZoomObj是需要缩放的UI
    private void ZoomImgByMousePos(GameObject ZoomObj)
    {
        //判断鼠标滚轮是否滚动
        if (Input.GetAxis("Mouse ScrollWheel") == 0)
            return;

        //一些变量的声明
        RectTransform RectTran = ZoomObj.GetComponent<RectTransform>();
        float PivotX = RectTran.pivot.x;
        float PivotY = RectTran.pivot.y;
        float OffsetX = 0f;
        float OffsetY = 0f;
        Vector2 addOffset;

        //获取轴心点在屏幕的坐标
        previewPosition = Camera.main.WorldToScreenPoint(RectTran.position);

        //获取鼠标坐标
        newPosition = Input.mousePosition;

        //计算偏差值
        addOffset = newPosition - previewPosition;

        //计算轴心点偏移量
        if (RectTran.rect.width != 0 && ZoomObj.transform.localScale.x != 0)
            OffsetX = addOffset.x / RectTran.rect.width / RectTran.localScale.x;
        if (RectTran.rect.height != 0 && ZoomObj.transform.localScale.y != 0)
            OffsetY = addOffset.y / RectTran.rect.height / RectTran.localScale.y;

        //计算轴心点新值
        RectTran.pivot += new Vector2(OffsetX, OffsetY);

        //计算UI新位置
        RectTran.anchoredPosition += addOffset;

        //放大UI
        if (Input.GetAxis("Mouse ScrollWheel") > 0)
            ZoomObj.transform.localScale += (ZoomObj.transform.localScale.x >= MaxScale - 0.1f ? Vector3.zero : Vector3.one * 0.1f);
        else if (Input.GetAxis("Mouse ScrollWheel") < 0)
            ZoomObj.transform.localScale += (ZoomObj.transform.localScale.x < MinScale + 0.1f ? Vector3.zero : Vector3.one * -0.1f);
    }

Al comparar el artículo original, puede encontrar que se han realizado algunos cambios, incluidos algunos errores y principios de implementación. De hecho, no entendí muy bien el artículo original. Omitió demasiadas explicaciones, lo que me hizo llorar a mí, un experto en matemáticas y novato en Unity.

Explique el contenido del código clave. Primero, es necesario asignar valores a algunas variables dentro de la clase de script. Modifíquelos usted mismo.

Obtenga las coordenadas del punto de pivote en la pantalla.

//获取轴心点在屏幕的坐标
previewPosition = Camera.main.WorldToScreenPoint(RectTran.position);

Al convertir las coordenadas mundiales de la interfaz de usuario en coordenadas de pantalla, las coordenadas mundiales de la interfaz de usuario parecen estar donde se encuentra el punto de pivote de la interfaz de usuario en las coordenadas mundiales. Debido a que el punto de pivote no abandonará la pantalla, puede convertir y obtener el valor.

La razón por la que se coloca al principio es porque el punto de pivote cambiará cuando la interfaz de usuario se escale más adelante. Este desplazamiento no cambiará después de que finalice el bloque de código de escala de la interfaz de usuario. Habrá un retraso. Si se coloca al final, es probable que el valor modificado no se capture.

Calcular el valor de desviación

//计算偏差值
addOffset = newPosition - previewPosition;

Calcule la diferencia entre la posición del mouse y la posición en la pantalla del punto de pivote

Calcular el desplazamiento del punto de pivote

//计算轴心点偏移量
if (RectTran.rect.width != 0 && ZoomObj.transform.localScale.x != 0)
    OffsetX = addOffset.x / RectTran.rect.width / RectTran.localScale.x;
if (RectTran.rect.height != 0 && ZoomObj.transform.localScale.y != 0)
    OffsetY = addOffset.y / RectTran.rect.height / RectTran.localScale.y;

La distancia de desplazamiento del punto de pivote de la interfaz de usuario después de escalar se calcula a través del valor de desplazamiento. Esta distancia de desplazamiento se basa en la posición del mouse, porque la posición del punto de pivote está en la misma posición que el mouse de forma predeterminada. La distancia unitaria de las coordenadas de la pantalla es la misma que la distancia unitaria del sistema de coordenadas de anclaje, por lo que puede dividir directamente el valor de desplazamiento por el ancho y alto de la interfaz de usuario ampliada para obtener la distancia de desplazamiento del punto de pivote.

Calcular la posición del punto de pivote

//计算轴心点新值
RectTran.pivot += new Vector2(OffsetX, OffsetY);

Mover el punto de pivote a la posición del mouse.

 Calcular la posición de la interfaz de usuario

//计算UI新位置
RectTran.anchoredPosition += addOffset;

La posición de la interfaz de usuario debe agregarse con un valor de desplazamiento. Esta posición puede ser coordenadas locales o coordenadas de anclaje. Parece que el movimiento del punto de pivote de la UI irá acompañado del movimiento de la posición de la UI. Si no lo agrega, encontrará que la interfaz de usuario se desplazará a una cierta distancia de las coordenadas predeterminadas después de escalar. Esta distancia de compensación múltiple es el valor de compensación calculado anteriormente. La lógica específica no está clara, debe establecerse en la capa inferior de Unity.

2023/2/11 Registro de actualización

Los nuevos proyectos necesitan usar esta función. Como resultado, puedo encontrar errores al copiar el mío. Inmediatamente me enojé y comparé y solucioné el problema durante la noche para descubrir el problema.

  1. Los valores iniciales del Pivot del componente Transform que necesita escalar la UI deben ser 0,5 y 0,5.
  2. Los ajustes preestablecidos de anclaje del componente Transformar que escala la interfaz de usuario deben ser los del medio

La configuración es la siguiente:

2023/6/9 Registro de actualización

Algunos amigos en los comentarios tuvieron un problema. Por un momento pensé que podría haber personas que no están muy familiarizadas con la interfaz de usuario y no expliqué claramente en qué circunstancias se usó este código, así que me gustaría agregar un un poco.

Este código se utiliza con el componente Scroll View. Scroll View no puede bloquear los ejes X e Y. (Configurar como se muestra a continuación)

 

El ZoomObj en el código generalmente se refiere al objeto Contenido en la Vista de desplazamiento.


Resumir

  1. ZoomObj en el código generalmente se refiere al objeto Contenido en la Vista de desplazamiento
  2. Los valores iniciales del Pivot del componente Transform (Contenido) que necesitan escalar la UI deben ser 0.5 y 0.5
  3. Los ajustes preestablecidos de anclaje del componente Transformar que escala la interfaz de usuario deben ser los del medio

Me da vergüenza decir que este artículo tiene una primera versión, enumeré algunos posibles problemas, pero me di la vuelta y caí en una trampa. En la primera versión, el tamaño de la pantalla y el tamaño de la interfaz de usuario eran los mismos, por lo que el efecto deseado se podía lograr por suerte. De hecho, si se cambiaba el tamaño de la interfaz de usuario, algo saldría mal. Luego dediqué unas horas más a corregir el error y revisé este artículo. El contenido de esta versión debería ser correcto.

De hecho, este efecto no es lo suficientemente bueno. Se siente como una tarjeta tras otra. De hecho, se puede mejorar reduciendo el valor de la rueda de desplazamiento y usando el bucle de rutina para hacer zoom varias veces para lograr el mismo efecto. Creo que esto ser más suave Por supuesto, requerirá más configuración. Pero soy demasiado vago, así que dejaré que todos lo optimicen ellos mismos.

Se recomienda experimentar usted mismo, cambiar de lugar y ver el efecto, que es difícil de entender con solo mirar el código. Si ha estado trabajando en proyectos de Unity2D, tarde o temprano encontrará este problema. Comprenderlo temprano puede profundizar su comprensión de los componentes de Unity. De todos modos, yo no lo hice.

Sería mejor si Unity tuviera una funcionalidad de escalado incorporada, ¿por qué no?

Finalmente, espero que pueda ayudar a los amigos que están en problemas y les deseo a todos buena suerte.

Supongo que te gusta

Origin blog.csdn.net/weixin_49779414/article/details/127498521
Recomendado
Clasificación