Here's a hint of how you can do what you want (sorry, I did it in C # by custom, but it's trivial to convert to javascript):
using UnityEngine;
using System.Collections;
public class Disparar : MonoBehaviour {
// Funçao de atualizaçao quadro a quadro
void Update () {
// So loga as informaçoes
Debug.Log (rigidbody.velocity.magnitude);
Debug.Log (noChao ());
// Acelera se o jogador apertar a tecla ESPACO
if(Input.GetKeyDown(KeyCode.Space))
acelera ();
// Quando detectar que a velocidade inverteu (ficou negativa no y e magnitude bem pequena,
// ou seja, o foguete parou la no alto), aplica uma força para girar.
if (!noChao () && rigidbody.velocity.y < 0 && rigidbody.velocity.magnitude <= 1)
//gira();
StartCoroutine(fazRetorno());
}
// Acelera se o jogador clicar no foguete
void OnMouseDown() {
acelera();
}
// Acelera o foguete aplicando uma força para a sua direçao "cima".
void acelera() {
rigidbody.AddForce(transform.up * 2000);
}
// Gira o foguete aplicando uma força para a sua direçao direita a partir de seu topo.
void gira() {
Vector3 ponta = transform.position;
ponta.y += renderer.bounds.size.y / 2;
rigidbody.AddForceAtPosition (transform.right * 20, ponta);
}
// Indica se o foguete esta colidindo com o chao
bool noChao() {
return Physics.Raycast(transform.position, -Vector3.up, collider.bounds.extents.y + 0.1f);
}
// Gira o foguete 180 graus sobre o eixo X, fazendo-o inverter completamente a direçao de subida
IEnumerator fazRetorno() {
Quaternion angulo = Quaternion.Euler(180, 0, 0);
float velocidade = 0.5f;
while(Quaternion.Angle(transform.rotation, angulo) > 0)
{
transform.rotation = Quaternion.Slerp(transform.rotation, angulo, Time.deltaTime * velocidade);
yield return new WaitForEndOfFrame();
}
transform.rotation = angulo;
}
}
Basically the idea is that from a user interaction (click or keyboard), a force is added to the rocket (I tested with a parallelepiped). At each frame, it checks whether the rocket stopped at the top (ie, it is not on the ground and the velocity on the y-axis has been inverted and is beeeemmm small - meaning the magnitude smaller than 1). If this happened, he simply applies another force on the top of the rocket to make it spin.
This example causes the rocket to go up vertically and slow down until it stops there at the top, then it will rotate and begin to fall vertically as well. You will need to adjust the strength values to get a nice effect as desired.
EDIT : I made a new function called fazRetorno
that does not use physics and simply rotates the rocket without adding any strength
side. Maybe this is closer than you want. She uses
Unity cool features that are the yield
command together with the function
Quaternion.Slerp
. Basically the execution of the loop ( while
) that has
within the fazRetorno
function is diluted over several frames (the
yield
does this) and rotation to 180 ° on the x-axis (the variable
angulo
indicates this) is "interpolated" according to the configured speed
in the velocidade
variable. Although this spin does not use physics,
that the "fall" of the rocket is all managed by the physics engine of the
Unity (that is, the only added force was in the beginning, at the moment of
launch). :)
If your game requires the rocket to be launched on a ballistic trajectory (a parabola), simply combine the vectors to add the force on the y (top) and x or z (front and side) axes at launch. To do this, simply add the vectors:
Vector3 forca = (transform.up * 2000) + (transform.right * 300);
rigidbody.AddForce(forca);
Using rigidbody.velocity
you can know the speed of the rocket at all times, and you can decide to open the parachute. It's another option.
I hope it helps.
Q.: For this example, your rocket must also have a collider
(ideally a box collider
) in addition to rigidbody
. :)