Currently, I have a script that uses AddTorque to simulate thruster control. What I want it to do is add torque areound whichever axis is receiving input. So, I’m doing this:
It works fine when I initially apply thrust to only one axis, but once it has rotated even a bit on one axis, adding toque on the other axes has it rotating in all sorts of wrong ways on wrong axes. What is the right way to script something basic like this?
For rotation on spaceship, dont use physics but use normal transform rotations. In the long run when you want to add auto pilot and some ai, you will have lots of math problems to solve otherwise.
Ok, but assuming I’m going to use AddTorque, how would I do it? Is it that the rigidbody is viewed in world space versus local space?
To further clarify what I want to accomplish, I want the ship to rotate around each axis independent of the others’ rotations. If I start the ship rolling around its z-axis, and then pitch the ship up on the x-axis, and then input to roll the opposite direction around its z-axis, it should do that. I thought AddRelativeTorque() was the solution, suspecting the problem was that AddTorque() was using the world axes, but the same problem is occurring. I found a post by Andeeee somewere that suggested something like:
AddTorque(Vector3.up*amount)
How is that different from:
AddRelativeTorque(Vector3.up*amount)
And another question I have…Transform.Rotate() uses euler angles. Problem is, euler angles result in gimbal lock in certain situations. What is the Quaternion equivalent to the Transform.Rotate() function?
As you say, AddTorque works in world coordinates, so adding torque around Vector3.up will turn around the world Y axis. A freely-rotating object in space can actually be quite difficult to control in two axes, so you might need to help the player out by simplifying one axis or adding a bit of stabilising.
The equivalent to transform.Rotate can be accomplished by using quaternion multiplication. Just specify the rotation corresponding to the change you want (ie, the parameters you would pass to transform.Rotate) and then multiply the existing rotation by this new quaternion:-
var change = Quaternion.Euler(0, 90, 0);
transform.rotation *= change;
Yes, Andeee. I have already designed in auto-stabilization. Trust me, I understand. The first time I tried it manually, I was all over the place. Thanks. I will take another stab at it tonite and see if I can’t get it to work.
I’m working on something similar my self, and I was wondering if your using torque for your rotations to achieve a particular effect / style of rotation motion; or if you are just trying to figure out how to make the craft rotate around it’s axis? If you just want it to rotate you can use a (transform.rotate * input axis ) set to you local axis.
This is what I’m using to get that classic X-wing / Freespace / X3 feel.
If you are using joystick controls, what are you using for your throttle. I cannot get unity to recognize my throttle slider.
When I get home I can post the code for my X,Y,Z, rotation controls.
I am using torque to control the ship. I originally had it worked out to be done through the transform, but the math involved is a lot easier using AddTorque. I got it working, now that I have come to understand how AddTorque() works relative to world space.
var tVec = Vector3(Input.GetAxis("Pitch"*pitchThrust,Input.GetAxis("Yaw") *yawThrust,Input.GetAxis("Roll")*rollThrust);
rigidbody.AddTorque(transform.TransformDirection(tVec)*Time.deltaTime);
Not sure why so many are opposed to handling something like this using Physics versus direct transform manipulations. Handles just the same as far as I can tell.
Don’t you run into gimbal lock issues with that code? I had something which was essentially the same (maybe I’m missing something), but when I would rotate my ship 90 degrees along one axis, it would lock on me.
By the way, when using torque, remember that your angular acceleration around any given axis is not equal to the magnitude of the respective component unless you specify it as such with the ForceMode argument of the AddTorque() function.
I don’t have any problems with the code getting locked in on one axis or the other. The only problem i have is Unity not recognizing my throttle slider. I hope someone knows how to fix that, or if it just doesn’t work atm. http://forum.unity3d.com/viewtopic.php?t=55829
The key to the code i use is the Space.Self. Whith out it, it does freak out. So the code needs to know to look at your local XYZ and not the world XYZ.
Hey, Force. I had to go with the Transform.Rotate() approach, afterall. I liked AddTorque because it accounted for gradual build up of angular velocity accounting for mass of the ship, but to auto stabilize the ship, I needed a way to compare the local angular velocity with the target angular velocity. Can’t use rigidbody.angularVelocity because it is oriented to world space, and rotations are happening in local space.
So, I went with your method and just coded in the calculations to make the rotations acceleration values. Now, my ships don’t rotate at the same angular velocity. They accelerate to the target angular velocity, meaning larger ships take longer to get to target rotation velocities and take longer to stop rotating.
That’s awesome! I’m glad it helped you out. My next step is to build up a rotation and acceleration system similar to yours. I’m just working out how I would like things to react.
Hey, Force. I sent you a PM with my entire script as an attachment. Take a look at it. Use what you want from it. Whatever. I’m very pleased with it so far. I haven’t implemented it with the game proper, but just a little toying with it has yielded a good balance between realistic control and a complexity level that is accessible to most players with a little practice.
I don’t have main engines implemented in this script. Propulsion is a separate one, but acceleration for those can be done using the same basic principals that I used for the attitude controls. When I’m done with it, I’ll send it, too, if you like.
Wow that’s fantastic, I really appreciate you sharing. I’ve PM’d you back my test environment. It’s a Matrix filed of cubes that help to provide visual feedback during testing of velocity and rotation. I found this to be more useful than just placing a few static objects as reference points. I hope it’s something you can find useful.
I wanted to post a package that trys to emulate Descent, but I’ve been fooling with the Project Settings > Input Manager, and the package I built doesn’t seem to bring those changes along. Is there an easier way to share a project, like maybe zipping it up? http://www.stuffycorporatedesign.com/open/descentish.zip
Anyway, I was pumped to see this conversation.
The following seems to be a good start for what I had in mind for the test. I thought it might be related enough to be usefull, but I’m still an infant with Unity, so go ahead and laugh now, get it all out.
var flameParticle : GameObject;
function Awake (){
Screen.showCursor = false; //(hides the cursor)
flameParticle.renderer.enabled = false;//turn off gun to start with
Screen.lockCursor = true;
}
function Update(){
if (Input.GetButtonDown("Fire1")){
InvokeRepeating("GunFlash", 0,.05);
}
else{
CancelInvoke();
}
}
function FixedUpdate() {
//recalculate movedirection directly from axes
moveDirection = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Rise"), Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
rigidbody.AddForce (moveDirection * 20);
rollDir = transform.TransformDirection(Input.GetAxis("Mouse Y")*2, Input.GetAxis("Mouse X")*2, Input.GetAxis("Roll")*-.25);
rigidbody.AddTorque (rollDir);
}
function GunFlash(){
if(flameParticle.renderer.enabled){
flameParticle.renderer.enabled = false;
}
else{
flameParticle.renderer.enabled = true;
}
}
Pauly, that’s basically the same premise for what I was doing when I was using AddTorque. My stumbling block there, however, was handling the autostbailization of my ship, whereby, when the user stopped giving input (meaning the ship should stop all rotations on any axis with zero input), counter torque would be applied to stop the ship (rather than the artificial method of just stopping them cold). I was having trouble figuring out how to determine the local angular velocity of the rigidbody to determine the amount of counter-torque needed, so I abandoned that path and went to direct transform manipulation.
I think I understand now. I’m imagining a “navigational computer” that counters rotation with automated thrusts, instead of the “mysterious drag” that I used. In other words, you’re looking for something a bit more sim-ish and exact? I’ve been assuming that I could explain away the mystery drag by adding thruster effects when the user wasn’t adding input, and make the thruster graphics proportional to the amount of spin. Hope that made sense.
Haha… My reasoning was the use of inertial dampener or external thrusters to account for the offset. This I think also allows for an extra level of upgrade-ability.
Ok I had an idea. We want rotation to ease out over time. Say 2 seconds. How about having a timer that counts down two seconds and multiplies by the rotation thrust velocity. So as the count down timer approaches 0 you slow down until you stop. This could be applied to thrust also to make it take time to accelerate after the throttle slider has been moved.
Some thing like:
CountdownTimerY = (Count Down Math Here)
CountDownYaw = (CountdownTimerYRotationThrustLastRotationAngelFromAxis)
if(Yaw != 0) {
transform.Rotate (0, CountDownYaw* Time.deltaTime * PitchYaw * 1 , 0, Space.Self);
I’m sure there’s more that’s required but it’s the principal I wanted to get out there. Let me know what you guys think. I’ll start working on this after I get home and see what happens.
If anyone can tell me a good way to convert the rigidbody.angularVelocity values from world to local, I will give you the script for auto-counter thrust using AddTorque().
ForceX, the script I gave you will work with AddTorque with a little modification. I just need to figure out that one piece of the puzzle I mentioned above. But, as it is, the script is simulating proper torque with a given thrust-to-mass ratio anyway. When it slows itself down, it is due to calculated counter torque that is converted into rotation acceleration values. Essentially, it is simulating counter thrust. It just does all the math that AddTorque does for you.