En este momento estás viendo Cómo mover un proyectil a través de posiciones en un momento dado, independientemente del recuento de posiciones

 – Unity

Cómo mover un proyectil a través de posiciones en un momento dado, independientemente del recuento de posiciones – Unity

Cómo mover un proyectil a través de posiciones en un momento dado, independientemente del recuento de posiciones

– UnityAssets3Free

bienvenido , me llamo Camilo y para hoy os traigo
nueva pregunta

Quiero leer un proyectil a través de una lista de posiciones en un momento dado.

Mi código funciona cuando el recuento de posiciones no es demasiado alto, pero cuando la lista contiene mil puntosel tiempo que tarda el proyectil no es el mismo, claramente aumenta.

Mi código para mover el proyectil es el siguiente:

public float timeToMove = 3;
public GameObject projectile;
public ParabolaDrawer parabolaDrawer; //this class generates the list of the points

private int currentPosIndex = 0;
private Vector3 currentPos = new Vector3();
private List<Vector3> parabolaPointsPositions = new List<Vector3>();
private bool hasArrivedToPos = false;
private bool hasArrivedToLastPos = false;

[ContextMenu("LaunchProjectile")]
private void LaunchProjectile()

    currentPosIndex = 0;

    hasArrivedToPos = false;
    hasArrivedToLastPos = false;
    
    parabolaPointsPositions = parabolaDrawer.parabolaPoints; //returns a List<Vector3>
    projectile.transform.position = parabolaDrawer.parabolaPoints.ElementAt(0);
    currentPos = projectile.transform.position;

    StartCoroutine(MoveProjectileThroughTheParabola(timeToMove));


private IEnumerator MoveProjectileThroughTheParabola(float timeToMove)

    float timeToMoveToNextPosition = timeToMove / (parabolaPointsPositions.Count - 1);
    float step = 0f;
    Vector3 initialPos = parabolaDrawer.initialPosition;

    while (step < 1 && !hasArrivedToLastPos)
    
        // Move our position a step closer to the target.
        step += Time.smoothDeltaTime / timeToMoveToNextPosition; // calculate step distance to move in stablished time
        projectile.transform.position = Vector3.Lerp(initialPos, currentPos, step);

        //Check if arrived to the point
        if (Vector3.Distance(projectile.transform.position, currentPos) <= 0.001f)
            hasArrivedToPos = true;

        if (hasArrivedToPos)
        
            //Check which is the next point or if has arrived to the last one
            if (currentPosIndex == (parabolaPointsPositions.Count - 1))
                hasArrivedToLastPos = true;
            else
            
                initialPos = currentPos;
                step = 0f;
                currentPosIndex++;
                currentPos = parabolaPointsPositions.ElementAt(currentPosIndex);
                hasArrivedToPos = false;
            
        
        yield return null;
    

Mi prueba fue establecer timeToMove a 3, e intenta mover el objeto 1000 puntos en estos 3 segundos, tarda 10.

creo que el problema es deltaTime siendo mayor que timeToMoveToNextPositionpero no estoy seguro de cómo solucionarlo, debo calcular currentPosIndex ¿de una manera diferente?

Editar: proporcionar información sobre la respuesta @ NSJacob1

Si entiendo correctamente, ¿es este el código final usando su método?

private IEnumerator MoveProjectileThroughTheParabola(float timeToMove)

    Vector3[] points = parabolaDrawer.GetParabolaPoints().ToArray();
    float elapsedTime = 0;
    float duration = timeToMove;
    while(elapsedTime < duration)
    
        elapsedTime += Time.deltaTime;
        float pathPosition = Time.deltaTime / duration;
        float indexPosition = pathPosition * points.Length;

        int left = Mathf.FloorToInt(indexPosition);
        int right = Mathf.CeilToInt(indexPosition);
        float t = indexPosition - left;

        Vector3 position = Vector3.Lerp(points[left], points[right], t);
        projectile.transform.position = position;
        yield return new WaitForEndOfFrame();
    

Edit2: Sigue mejorando con la información de los comentarios de @NSJacob1

private IEnumerator MoveProjectileThroughTheParabola(float timeToMove)
   
    Vector3[] points = parabolaDrawer.GetParabolaPoints().ToArray();
    elapsedTime = 0;
    duration = timeToMove;
    indexPosition = 0;
    pathPosition = 0;
    right = 0;
    left = 0;

    while (right < points.Length)
    
        pathPosition = elapsedTime / duration;
        indexPosition = pathPosition * points.Length;

        left = Mathf.FloorToInt(indexPosition);
        right = Mathf.CeilToInt(indexPosition);

        if(right < points.Length)
        
            t = indexPosition - left;
            position = Vector3.LerpUnclamped(points[left], points[right], t);
            projectile.transform.position = position;
        
        else
        
            projectile.transform.position = points.Last();
        
        elapsedTime += Time.smoothDeltaTime;
        
        yield return null;
       

1 respuesta 1

Si se mueve de un punto a otro, obtendrá un retraso basado en la cantidad de veces que necesita cambiar conjuntos de puntos. Trate de pensar en el conjunto completo de puntos como un camino y decida desde dónde como un flotador. [0, 1]estás en ese camino.

Si todo el camino se recorre en 3 segundos y hay 1000 puntos, 1,5 segundos es 0,5f a lo largo de nuestro camino, o 500 puntos.

Aquí hay un ejemplo:

private IEnumerator MoveProjectileAlongPath(float timeToMove)

    Vector3[] points = path;
    float duration = timeToMove;
    float start = Time.time;
    float elapsed = 0;
    // Time.deltaTime is the duration of a single frame,
    // so this will set position to "after one frame of movement"
    while (elapsed < duration )
    
        elapsed = Time.time - start;
        float pathPosition = elapsed / duration; // our [0, 1] value
        float indexPosition = pathPosition * points.Length; // position in path

        int left = Mathf.FloorToInt(indexPosition);
        int right = Mathf.CeilToInt(indexPosition);
        if (right >= segments)
        
            transform.position = path[points.Length - 1];
            break;
        
        float t = indexPosition - left; // percent between left and right position

        transform.position = Vector3.Lerp(points[left], points[right], t);

        yield return null;
    

Si realiza un seguimiento de su posición de ruta anterior o el tiempo visto hasta ahora, puede construir en cada marco. No dar un paso hacia una meta, sino descubrir dónde se encuentra todo el camino e ir directamente allí.

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 funcione

Deja una respuesta