Estoy trabajando en un juego en el que el jugador puede recoger objetos usando algo como un rayo tractor y transportarlos.
Atraer el objeto hacia el centro de la viga no es difícil. Pero una vez que el objeto está lo suficientemente cerca del centro, necesito mantenerlo allí mientras el jugador se mueve, que es con lo que tengo problemas. Se me ocurren dos formas de hacerlo, y ambas tienen problemas:
Actualice la posición del objeto cada vez que cambie la posición del jugador, manteniéndolo centrado en la viga.
Actualice la velocidad del objeto para apuntar directamente hacia el centro del haz, cuanto más lejos, más velocidad.
Mover y rotar funciona bien con ambos enfoques, pero la física es incorrecta cuando el objeto transportado choca con otros objetos:
Con el primer enfoque, la física se ignora por completo. El objeto transportado simplemente empuja cualquier cosa fuera del camino. Esto se debe a que los cambios de posición solo se deben realizar como parte de la física mundial, en función de la velocidad.
Con el segundo enfoque, la física básicamente se comporta como debería, pero reacciona de forma exagerada. El problema es: para mantener el objeto transportado en el centro de la viga incluso cuando gira y se mueve, necesito usar valores de alta velocidad. Entonces, una vez que el objeto transportado toca otro, obtiene demasiada velocidad de la colisión.
¿Cómo puedo implementar esto correctamente? Mi mejor suposición en este momento es ir con el segundo enfoque y agregar un manejo especial para los objetos transportados a la física mundial, reduciendo la velocidad a valores razonables para colisiones o cuando el jugador deja de transportarlos. Pero eso parece una solución poco elegante.
Editar: Agregar un pseudocódigo para ilustrar cómo funciona en este momento (ese sería el segundo enfoque anterior)
void attract_object(object, ticks) {
Vector distance = beam_center - object.center;
// If the object is not close to the beam center, attract it slowly
if (magnitude(distance) > 10) {
object.velocity += distance.normalized() * ticks * 0.1;
return;
}
// Here comes the part we're talking about. That magic 0.5 is just high enough
// that the object isn't lost while moving around. But it's still so high that
// other objects are repelled with way too much force.
object.velocity = distance * ticks * 0.5;
}
Por lo que veo, esto sucede cuando el objeto transportado empuja a otro objeto:
- El objeto transportado choca con otro objeto.
- Las velocidades de los objetos se distribuyen correctamente, por lo que el objeto transportado se aleja del centro del haz en el proceso.
- El código anterior hace que el objeto transportado regrese al centro del haz, con tanta velocidad que volverá allí rápidamente
- Cuando el objeto transportado se mueve hacia el centro del haz, la mitad de su alta velocidad se transfiere al otro objeto y lo repele violentamente. Dado que la velocidad inicial del objeto transportado parece ser sensata, puedo imaginar que los pasos 2 a 4 se repiten varias veces, lo que genera una velocidad tan alta.
Esa parece ser la causa. Sin embargo, no puedo pensar en una buena manera de solucionarlo :(