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 timeToMoveToNextPosition
pero 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