Darse cuenta del retraso de los elementos 2D en la unidad para seguir el movimiento del mouse

Primero, diseñe el diagrama de efectos.

No sé si ha conseguido el efecto que deseas. De todos modos, estoy bastante satisfecho. La imagen no muestra cómo se detiene. Mientras sus coordenadas sean consistentes con las coordenadas del mouse, no se moverá.

De hecho, he probado los métodos de otras personas, pero la mayoría de los artículos son iguales, son para 3D y están escritos así.

this.transform.LookAt(mousePosition);
this.transform.Translate(Vector3.forward * 1f * Time.deltaTime,Space.Self); 

Si utiliza el método que se encuentra en Baidu, el elemento 2D se volteará. La razón es la función LookAt, que hará que el elemento mire en la dirección del mouse. Unity no parece tener una función LookAt para elementos 2D. Después Todos, reescribe una Las funciones siguen siendo una pérdida de tiempo. Utilice las ya preparadas si puede. Sin embargo, cuando buscaba información, encontré otra solución mejor, que mencionaré más adelante.

Luego hablemos de la implementación del código.

Al principio, lo hice yo mismo. Pensé que su lógica de implementación debería ser acercar la posición del objeto del juego a la posición del mouse. No pude encontrar ninguna función lista para usar en Unity, así que tuve que escribir una yo mismo.

Encontré muchas dificultades cuando comencé a escribir. Sería relativamente simple hacer que la posición del objeto del juego fuera consistente con la posición del mouse, pero aún así encontraría un problema.

Es decir, los ejes de coordenadas de las coordenadas del mouse en la pantalla y las coordenadas de los objetos en el juego son diferentes, y sus unidades son diferentes, por lo que cuando se ejecuta por primera vez, sale volando directamente de la pantalla. Afortunadamente, no volaba en una dirección todo el tiempo. Descubrí este problema a través de su comportamiento de volar a un área determinada y luego comenzar a dar vueltas alrededor de un punto, y luego Baidu resolvió este problema.

Se puede solucionar con un fragmento de código.

mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);

El significado de este código es convertir las coordenadas de la pantalla del vector3 del mouse en las coordenadas del juego.

La siguiente dificultad es calcular su distancia, que es conocimiento de la escuela secundaria, pero todavía me toma más de diez minutos retomarlo.

El principio matemático específico es este

 Primero declare las variables, mouse es la coordenada del mouse, item es la coordenada del objeto del juego, item es el origen del eje de coordenadas bidimensional, L es la distancia en línea recta entre el mouse y el item, X es la distancia en línea recta entre el mouse y el eje de coordenadas X, e Y es la distancia entre el mouse y el eje de coordenadas X. La distancia en línea recta del eje de coordenadas Y, l es la distancia que el elemento puede moverse en un cuadro , x es la distancia en línea recta del artículo desde , las coordenadas del artículo y el tamaño de l, encuentre los tamaños de x e y

Bueno, así se expresa cuando se escribe como una pregunta de matemáticas, la pregunta es muy larga, pero no es difícil. Mi solución es esta:

 Tanto X como Y se pueden encontrar mediante dos coordenadas, y luego x e y se pueden calcular mediante la fórmula de triángulos similares.

El problema matemático está resuelto, pero todos sabemos que hacer juegos es mucho más complicado que esto, de hecho, tenemos que considerar dónde está ubicado el mouse en el elemento, ¿arriba a la izquierda? ¿Abajo a la derecha? Entonces, ¿cómo solucionarlo?

Mi código es el siguiente:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class player : MonoBehaviour
{
    [Header("变量")]
    public Collider2D playerCollider;
    public Vector3 mousePosition;
    public Vector3 emtpyVector2;
    public Vector3 emtpyPosition;
    public float totalLength;
    public float playerSpeed;

    // Start is called before the first frame update
    void Start()
    {
        playerCollider = GetComponent<Collider2D>();
    }

    // Update is called once per frame
    void Update()
    {
        Move();
    }

    void Move()
    {
        mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        emtpyPosition = playerCollider.gameObject.transform.position;
        totalLength = Mathf.Pow(Mathf.Pow(mousePosition.x - emtpyPosition.x,2) + Mathf.Pow(mousePosition.y - emtpyPosition.y,2), 0.5f);

        if (playerSpeed > totalLength)
            emtpyVector2 = Cal(totalLength, mousePosition.x - emtpyPosition.x, mousePosition.y - emtpyPosition.y, totalLength, emtpyVector2, mousePosition, emtpyPosition);
        else
            emtpyVector2 = Cal(playerSpeed, mousePosition.x - emtpyPosition.x, mousePosition.y - emtpyPosition.y, totalLength, emtpyVector2, mousePosition, emtpyPosition);

        if(mousePosition.x != emtpyPosition.x || mousePosition.y != emtpyPosition.y)
        {
            playerCollider.gameObject.transform.position = new Vector3(emtpyPosition.x + emtpyVector2.x, emtpyPosition.y + emtpyVector2.y, emtpyPosition.z);
        }
    }

    Vector2 Cal(float passLength, float x, float y, float totalLength, Vector2 vector2, Vector2 mousePosition, Vector2 playerPosition)
    {
        vector2.x = passLength / totalLength * x;
        vector2.y = passLength / totalLength * y;
        
        return vector2;
    }
}

Por favor, ignore el hecho de que mi base de codificación es deficiente. Todas las variables se declaran como públicas porque quiero ver la relación entre ellas. Ahora extraigamos las partes principales y echemos un vistazo.

void Move()
    {
        mousePosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        emtpyPosition = playerCollider.gameObject.transform.position;
        totalLength = Mathf.Pow(Mathf.Pow(mousePosition.x - emtpyPosition.x,2) + Mathf.Pow(mousePosition.y - emtpyPosition.y,2), 0.5f);

        if (playerSpeed > totalLength)
            emtpyVector2 = Cal(totalLength, mousePosition.x - emtpyPosition.x, mousePosition.y - emtpyPosition.y, totalLength, emtpyVector2, mousePosition, emtpyPosition);
        else
            emtpyVector2 = Cal(playerSpeed, mousePosition.x - emtpyPosition.x, mousePosition.y - emtpyPosition.y, totalLength, emtpyVector2, mousePosition, emtpyPosition);

        if(mousePosition.x != emtpyPosition.x || mousePosition.y != emtpyPosition.y)
        {
            playerCollider.gameObject.transform.position = new Vector3(emtpyPosition.x + emtpyVector2.x, emtpyPosition.y + emtpyVector2.y, emtpyPosition.z);
        }
    }

    Vector2 Cal(float passLength, float x, float y, float totalLength, Vector2 vector2, Vector2 mousePosition, Vector2 playerPosition)
    {
        vector2.x = passLength / totalLength * x;
        vector2.y = passLength / totalLength * y;
        
        return vector2;
    }

Ya se ha mencionado antes cómo obtener y convertir las coordenadas del ratón, y luego la distancia entre ambos se calcula mediante la fórmula de que la suma de los cuadrados de ambos lados del triángulo rectángulo es igual al cuadrado de la hipotenusa, es decir es, longitud total

En la función Cal, implementé la función de calcular xey, y usé un vector2 para devolver estos dos valores.

Hay dos situaciones en las que llamo a esta función de cálculo. Una es que la distancia móvil es menor que la distancia entre el elemento y el mouse, es decir, l <L. Si este es el caso, se pasa la distancia móvil, es decir , el primer parámetro se pasa l, la distancia que puede moverse el elemento, en caso contrario se pasa L, la distancia entre los dos, de esta forma las coordenadas del elemento coinciden completamente con las coordenadas del mouse y el movimiento se detiene. No es necesario volver a explicar los principios matemáticos, ¿verdad?

Otro error que encontré al escribir código es el positivo y el negativo de x e y. Debes prestar atención a esto. Si el mouse está en la esquina inferior izquierda del elemento y tu x e y son números positivos, entonces Se irá El ratón se fue volando en la dirección opuesta, adiós.

Por mi parte, debido a que totalLength es un número positivo después de la raíz cuadrada, passLength solo será un número positivo, por lo que depende del signo de x e y entrantes, lo que resuelve este problema.

El segundo es cómo determinar si las coordenadas del elemento y las coordenadas del mouse coinciden. No puedes usar transform.position directamente para comparar. Aunque el juego se estaba ejecutando en ese momento, los errores seguían reportándose en segundo plano. Parece que el dos no son completamente iguales solo porque las coordenadas son iguales. El efecto permanece sin cambios, pero intentará asignar un valor nulo al elemento, por lo que el fondo sigue informando errores. Luego lo cambié y se solucionó.

Este es un método estúpido, de acuerdo con la idea de nunca engañar a los demás, revisé la información nuevamente y encontré un método mejor.

La función Vector2.Lerp puede lograr la misma función que mencioné anteriormente, así que no la reescribiré. Si está interesado, puede ir a este enlace para leer directamente la descripción del documento oficial de la función Vector2.Lerp.

El aprendizaje no tiene fin. Bueno, todas las dificultades técnicas que se deben explicar han terminado. Esta es la primera vez que comparto la tecnología relevante sobre unity. Si tienes alguna pregunta, no dudes en dejar un mensaje, aunque rara vez vengo a verlo. Si quieres hacer juegos independientes conmigo, contáctame (estoy pensando en una propuesta)

Supongo que te gusta

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