- Home /
RigidBody movement with AddForce
So I´ve been working on a spaceship controls for a few days and I got a decent script, but I ran into a problem and I dont know how to fix it.
The game is kinda like All Range Mode in Starfox 64, you can move freely in X, Y an Z and all that stuff. The problem is that when a bullethits my RigidBody shield sometimes collides, some other not =(
I read some docs and it says that using transform to move a RigidBody it´s not the best choice so I tried to use AddForce... and I failed =D
I end up moving too fast, or not moving at all, either way I couldn´t control the ship
so if anyone can help me turn this transform movement script into a AddForce movement script I would really aprecciate it.
void Movimiento()
{
//Velocidad
if(gameObject.rigidbody.velocity.magnitude < VelNaveMax ) //Compara si la velocidad es menor a a la velocidad maxima, si es verdadero...
{
gameObject.rigidbody.velocity = transform.forward * VelNave; //mueve la nave hacia adelante en una cantidad definida por la vel del motor
}
//Vuelta
if(Input.mousePosition.x < (Screen.width / 2) + 70) //Si el mouse se encuentra a la izquierda
{
transform.Rotate (0,-Rotacion,0); //rota la nave una cantidad negativa definida en la variable rotacion
}
if(Input.mousePosition.x > (Screen.width / 2) - 70) //Si el mouse se encuentra a la derecha
{
transform.Rotate (0, Rotacion,0); //rota la nave una cantidad definida en la variable rotacion
}
//Subir/bajar
if(Input.mousePosition.y < (Screen.height / 2) + 70) //Si el mouse se encuentra abajo
{
transform.Rotate (Rotacion,0,0); //Rota hacia abajo la nave
}
if(Input.mousePosition.y > (Screen.height / 2) - 70) //Si el mouse se encuantra arriba
{
transform.Rotate (-Rotacion,0, 0); //rota el objeto hacia arriba
}
//Girar
if(Input.GetAxisRaw ("Horizontal") > 0){ //Mientras se presione "A"
transform.Rotate (0,0, -Rotacion); //Gira la nave a la derecha
}
if(Input.GetAxisRaw ("Horizontal") < 0){ //Mientras se presione "D"
transform.Rotate (0,0, Rotacion); //Gira la nave a la izquierda
}
//Acelerar
if(Input.GetAxisRaw ("Vertical") > 0 && VelNave <= VelNaveMax){ //Mientras se presione "W"
if((VelNave + 10) < VelNaveMax && Acelerando == false){ //Si el aumento de velocidad no supera la velocidad maxima
VelNave = VelNave + 10; //Aumenta la velocidad de la nave en 10
Acelerando = true;
StartCoroutine (Reset ());
}
}
Please, keep variable names and comments in English, otherwise no-one can understand what it means. This is a general guideline for clean code, since English is the international language and everyone should be able to understand it.
Answer by yezzer · Apr 14, 2012 at 07:53 AM
A tip: For this kind of behaviour, you'll need to apply it over several frames, as it's a continuous force.
http://unity3d.com/support/documentation/ScriptReference/Rigidbody.AddForce.html
"If you want to apply a force over several frames you should apply it inside FixedUpdate instead of Update"
You'll also either want to use ForceMode.Force or ForceMode.Acceleration.
Yeah void $$anonymous$$ovimiento() is called from Fixed Update, but thanks n_n
Answer by fafase · Apr 14, 2012 at 08:13 AM
I think you are dealing with frame space problem. If the projectile hitting your ship is moving real fast, it might happen that not collision occur.
ex: your bullet moves at 500m/s, for 50fps (to simplify) you have 10/frame so:
at t:0 it is at 0
at t:1 it is at 10
at t:2 it is at 20 and so on
So if you are at 15 and less than 5m wide, there will be no collision.
That is why you should use raycast to check collision at high velocity and then the actual projectile is just there for the visual effect.
You can also try to use continuous collision detection. This is from the rigidbody documentation:
Continuous Collision Detection
Continuous collision detection is a feature to prevent fast-moving colliders from passing each other. This may happen when using normal (Discrete) collision detection, when an object is one side of a collider in one frame, and already passed the collider in the next frame. To solve this, you can enable continuous collision detection on the rigidbody of the fast-moving object. Set the collision detection mode to Continuous to prevent the rigidbody from passing through any static (ie, non-rigidbody) MeshColliders. Set it to Continuous Dynamic to also prevent the rigidbody from passing through any other supported rigidbodies with collision detection mode set to Continuous or Continuous Dynamic. Continuous collision detection is supported for Box-, Sphere- and CapsuleColliders.
Now if this does not do the trick the way you want, you should use raycast. That will send an invisible ray (invisible in the game) in front of the object and report if the ray collides with anything. Just like the blind man cane.
http://unity3d.com/support/documentation/ScriptReference/Physics.Raycast.html
Your answer
Follow this Question
Related Questions
What is the best way to move the player with physics without using MovePosition? 0 Answers
Circular movement of gameobject with rigidbody 1 Answer
[Solved]Why doesn't this Rigidbody.AddForce work the way I tell it to? 1 Answer
Rigidbody falling very slow 1 Answer
Rigidbody movement conflict? 1 Answer