- Home /
Rigidbody.addforce then rigidbody.rotation and movement along transform.forward
Hello, I am novice with scripting and rigidbody and need some info.
I use rigidbody.addforce to get my gameobject moving.
I then use rigidbody.rotation to change the gameobject orientation (which, of course, changes transform.forward as well).
When I do this the gameobject continues to move along it original trajectory.
How can I get my gameobject to move, at all times and maintain speed, along what I set for rigidbody.rotation (always move along transform.forward)?
My gameobject is a plane (or a car, etc) that the player can turn. Am I possibly going about this the wrong way and should not be using rigibody for objects that change direction under user or script control?
Appreciate any help!
Answer by sparkzbarca · Jan 31, 2013 at 08:52 PM
you are aware that that is basically a character controller, what your asking for?
it's not that your continuing to move along the original traj it's that your moving along both. It's like in space, you start traveling forward, now if you turn left and start going that way you do start going that way, but because there is nothing to stop your previous movement your going what is now your "right" + your new "forward". so your going diagonally.
Is this on the ground? A simple increase in friction would probably right the issue real quick (if the friction is high enough the forces moving the wrong direction would quickly dissipate, much like they actually do for a car, a car can only drift with a large amount of force, that force is quickly overcome by friction)
if it is in the air then drag would be the co efficient to change. If your using rigidbody the most realistic way to modify movement is through forces and counter forces.
otherwise you can rotate and set velocity
velocity = transform.forward * current_speed
that wouldn't cause any loss of speed though during the rotation, would instantly set your speed which could be wierd. its not realistic but its quick.
Well.... I think I know that this is a character controller :-0...
I am still getting my head around Unity and industry ter$$anonymous$$ology on game physics.
Certainly I understand real world physics concepts and when an object is pushed it moves along its original trajectory until pushed again.
$$anonymous$$y understanding of a character controller is that these are scripts (unity supplied or written).
So if that is correct than I am writing my own character controller for an airplane. Just finished coding a pitch/yaw/roll ability in the script which works fine. I am using rigidbody.rotation() to make adjustments to the airplane orientation.
But not clear on what the convention in Unity should be for moving my airplane while being able to control its movemment direction through rigidbody.rotation(). I though I was reading use rigidbody.addforce() to move the object. But my issue is that airplane continues to move along the trajectory of the addforce after I change pitch/yaw/roll using rigidbody.rotation().
I do not that if I addforce again now the movement moves towards being correct on the new transform.forward of my plane. But I don't want to addforce again, just maintain current speed in the new direction.
So I think I need advice on how I should move my plane so I can control its pitch/yaw/roll and have it move in its transform.forward direction.
Should I not use rigidbody.addforce to move my airplane? And use velocity = transform.forward * current_speed for movement?
no this isn't a character controller
the game component
Character Controller
is a character controller. Its a simplified form of character control. It's normally only good for humanish models though because it works with a capsule collider. its designed to be an object that obeys collision detection but moves in a non physics manner. you dont add force you just tell it where to go kinda.
so i wasn't saying your aware that the thing your writing is a char controller I was saying you are aware of the existence of this componenet (you weren't it appears)
Since your doing an aircraft its not a good solution but yea.
Are you trying to make a realistic flight sim? A$$anonymous$$A simulating the forces of lift,drag,gravity,thrust,angular momentum?
That is a hugely involved process.
Your saying you dont want to keep adding force, but if your wanting to make it realistic you do in fact want to add force.
An engine is constantly adding force, its that you also want to mess with the objects drag ratio.
Except if your looking for realistic flight you'll need to make up a custom drag equation to more accurately represent the specifics of flight as opposed to ground based drag.
Are you wanting a realistic one or a simle one?
the problem that i see is that you seem to want to have it both ways, you want a simple movement, yet you want to use a rigidbody which is a complex method of moving an object.
If you'd like simple movemnt
use a character controller
or
use a is$$anonymous$$inematic rigidbody but only move it during FixedUpdate so you get collisions and use a
tranform.position(vector3 position)
to move it around
if you want a complex movement your going to have to add forces everyframe. You'll need 3 main functions.
A drag function, a thrust function and a lift function. you'll need to use addforceat(vector3 position, force) so you can add lift at the wings, that will allow you to bank properly.
you'll have to calculate the center of mass and all sorts of things.
NASA has some great resources on the equations
NASA BGA (beginners guide to aero)
there is also weight but gravity will take care of itself.
Thank you for the additional feedback, its clearing up a few things but seems I've got a ways to go with Unity physics.
And, please, you misunderstand. I have no idea what I want. I am reading and going by what I read but have no idea if that is the correct way to go for what I am implementing.
And I am realizing that physics thing in Unity is pretty extended and is far beyond what I am ready for.
So, I am not looking to create a realistic flight sim. $$anonymous$$ore of a standard fly arounnd in space and blow things up (gotta start somewhere). So I will establish maximum speed, maximum yaw/pitch/roll rates. I will also add in acceleration so the space plane (I said airplane, meant generic flying object, sorry) doesn't lurch forward, or lurch turn, etc.
I am fine to calculate these and keep my motion routines simple at this point.
I want collision detection. I have gotten this to work and have had success with OnCollison().
I am O$$anonymous$$ with tracking speed and orientation in my script that takes user input or does AI and applying to gameobject.
I have kinda read that updating an objects transform.position and transform.roation every frame is not the way to go so I started looking at rigidbody.roation and rigidbody.addforce.
Is updating transform.position/rotation the way to go for simple object movement with collision detection?
Answer by gfvfubb · Feb 01, 2013 at 12:20 AM
I have working code that does this exact thing for an example.
This was adapted from Angrybots, and I'm leaving out variable declarations cause that's obvious. They're floats and vector3s. You need to add a frictional cross force proportiortional to the difference between the forward vector and the velocity vector somewhere else if you want 'realistic' drag. I don't have that here but I can post another example if you want that.
Top section is from PlayerMoveController Update(), bottom from FixedUpdate of FreeMovementMotor from Angrybots demo and modified.
thrust += Input.GetAxis ("Vertical");
thrust = Mathf.Clamp(thrust, -maxthrust, maxthrust);
turn += Input.GetAxis ("Horizontal") ;
turn = Mathf.Clamp(turn, -maxturn, maxturn);
motor.facingDirection = Quaternion.Euler (0, turn / 60, 0) * motor.facingDirection;
//character.rotation = Quaternion.Euler (0, turn / 60, 0);
motor.movementDirection = motor.facingDirection * (thrust/60);
// Make sure the direction vector doesn't exceed a length of 1
// so the character can't move faster diagonally than horizontally or vertically
if (motor.movementDirection.sqrMagnitude > 1)
motor.movementDirection.Normalize();
function FixedUpdate () {
// Handle the movement of the character
var targetVelocity : Vector3 = movementDirection * walkingSpeed;
var deltaVelocity : Vector3 = targetVelocity - rigidbody.velocity;
if (rigidbody.useGravity)
deltaVelocity.y = 0;
rigidbody.AddForce (deltaVelocity * walkingSnappyness, ForceMode.Acceleration);
// Setup player to face facingDirection, or if that is zero, then the movementDirection
var faceDir : Vector3 = facingDirection;
if (faceDir == Vector3.zero)
faceDir = movementDirection;
// Make the character rotate towards the target rotation
if (faceDir == Vector3.zero) {
rigidbody.angularVelocity = Vector3.zero;
}
else {
var rotationAngle : float = AngleAroundAxis (transform.forward, faceDir, Vector3.up);
rigidbody.angularVelocity = (Vector3.up * rotationAngle * turningSmoothing);
}
}
// The angle between dirA and dirB around axis
static function AngleAroundAxis (dirA : Vector3, dirB : Vector3, axis : Vector3) {
// Project A and B onto the plane orthogonal target axis
dirA = dirA - Vector3.Project (dirA, axis);
dirB = dirB - Vector3.Project (dirB, axis);
// Find (positive) angle between A and B
var angle : float = Vector3.Angle (dirA, dirB);
// Return angle multiplied with 1 or -1
return angle * (Vector3.Dot (axis, Vector3.Cross (dirA, dirB)) < 0 ? -1 : 1);
}