Turret rotation issues

Im not new to programming in general, but i am very new to unity programming and 3D math types. I’ve been searching on the forums and documentation for the past few hours to no avail to sort my issue, so I’ve resorted to asking the question to you good people in the hope that it is a simple fix that I’m just missing.

I’m currently working on a little tank game as a tester project and trying to create a script to rotate the turret but all of the examples I have tried have rotated the turret in an odd way, I don’t seem to be able to lock the rotation to a specific axis and the turret end up looking something like this (looking at the blue tank):

Quaternion rotation = Quaternion.LookRotation(target.position - turretOptions.turret.position);
            turretOptions.turret.rotation = Quaternion.Slerp(turretOptions.turret.rotation, rotation, Time.deltaTime * turretOptions.damper);

Maybe it’s just my inexperience with using quaternions, and this is probably a simple fix to someone with a bit more know-how, but this is starting to get a little frustrating to say the lest :stuck_out_tongue:

Does anyone care to point me in the right direction with this?

Compute the rotation on a 2D Plane?
Quaternion.LookRotation( new Vector3(target.position.x, 0, target.position.z) - new Vector3(turret.position.x, 0, turret.position.z) );

If your tank is a rigid body and the turret of the tank is a rigid body too you can go to physics and add a configurable joint and actually lock the rotation on whichever axis you don’t want it to rotate it on and even limit of how much or how far can it look up and down too. In order to learn more about configurable joint you have to look it up on the actual unity manual or reference you won’t find it on the scripting reference.

And instead of quaternion angles why not try Euler angles in reality Euler angles are the actual angles of the model quaternion is like a different measure same as miles per hour versus kilometers per hour.
You can write something like transform.eulerangles.z = 0; for that rotation that you are trying to lock or stop but that if they are character controllers then you would code it like so. If I where you try using configurable joints specially if they are rigid bodies and make sure the actual turret of the tank has a collider and a rigid body attached to it to.

I had a similar problem once so hopefully this helps out tell me if it does work out and by the way I’m a newbie too in some way to unity but not on coding do.

To rotate on the Y axis only just zero out the axis’s you dont need.

Quaternion rotation = Quaternion.LookRotation(target.position - turretOptions.turret.position);
rotation.x = 0;
rotation.z = 0;
turretOptions.turret.rotation = Quaternion.Slerp(turretOptions.turret.rotation, rotation, Time.deltaTime * turretOptions.damper);

I’ve tried the above solutions and basically realized that the models imported from MAX is whats causing me the issue. The rotation values for the turret are coming in at 270,0,0 which is screwing up my original script and some of the ones above. The only way i can rotate it without bodging with rigidbody’s is to change the euler angles and calculate the amount to change by in my own method, i can’t use the Quarternion.RotateTo method or i end up aiming into space.

I can continue with this solution and improve it further but im wondering if there is any way to fix the MAX import first. I’ve used the xForm utility etc and everything is showing as 0,0,0 in MAX for rotation and positions but once i import it into Unity it’s changing. Is there something i’ve missed with this?

Thanks for the replies so far!

I doubt that will work as you expect (not in the general case at least).

Can’t comment on the import, but a common solution to this problem is to make the visual a child object and assign it a ‘corrective’ transform that aligns it the way you want it to be aligned.

Reset the transform in Max as you have done. Then go to … the tab i forget the name of … and choose “Affect Pivot Only”. Rotate the pivot +90 degrees about the x-axis. Turn “Affect pivot only” off again and your model should not have moved but it should have the rotation showing as 90,0,0. Now export to fbx with Y as the up axis. Your should then have your model correctly orientated when you import in into Unity with 0,0,0 rotation.

Ah interesting, I’ll attempt this once I get back from work later. I’ll post back with my results once I get to try it out, thanks a lot!

The method worked brilliantly, thanks Eagle32. The only problem i have now is that everything is backwards (the turret faces away from the target and the tank itself moves backwards instead of forwards), so I guess if I mess around with those export options a bit more I should be able to get it to export correctly and everything the right way around.

Thanks to everyone who helped :slight_smile:

I have been using it and never ran into any problems as long as you dont import stuff with funky axis’s.

                targetRotation = Quaternion.LookRotation(thisAgentsTransform.position + moveDirection - thisAgentsTransform.position);
                targetRotation.z = 0;
                targetRotation.x = 0;
                thisAgentsTransform.rotation = Quaternion.Lerp(thisAgentsTransform.rotation, targetRotation, faceSpeed * Time.smoothDeltaTime);

Used this in my (RTS) steering to keep units looking where they are moveing.

As I said earlier, it won’t necessarily work in the general case. It will however work in some cases (and it may be that these are the only cases that arise in your game).

If you drop the model into your scene is the tank orientated corretly with the move tools gizmo axis when you have it selected?

That will tell you if it’s a code problem or a problem with the orientation of your model.

If it’s the model:

  1. Is it correctly orientated in max? ie You are looking at the front of the model in the front view, left in the left, etc.

The model was incorrectly orientated in MAX, it’s all sorted and works brilliantly now. We did have a problem where the rotation was showing at -720 on the Y, but I think that was something to do with not adding in the model fresh each time we changed something and was relying on unity to do a file refresh and is sorted now.

It’s all new to me so I’m learning as I go and finding it very interesting.

EDIT: I thought it was all going fine until I decided to add in a debug line to show the target of the turret and now it seems that the turret is a few degrees off no matter where I place it. In the attached screen shot I’ve placed the tank directly behind the target and the Y of the turret is showing pretty much 360/0 which means it should be facing forwards, but it’s not.

The thing is though, when the turret is sitting in the editor with no script running, it’s 0 position is pointing directly forwards. Is this something to do with the MAX import again?

Good question, if you figure it out let me know because I have a model doing somthing similar, except mines changing position rather than rotation when I run my game. I haven’t had a chance to figure out what I did differently to break it yet as I had to switch to another project for a couple of weeks.

[edit] I had a quick look at mine, my problems got something to do with my bone based animation so it’s not the same problem you have.

It is very strange. The main problem i have is importing stuff from 3DSM, every time i do it things screw up, even if i was to create a brand new 3DSM project and model a tank out of 2 blocks (one for the body and one for the turret), as soon as i import it into unity the parent handles are correct, but the child handles are all weird with Z pointing up in the air (even after specifying that Y is up) and the rotation axis all screwed up. I’ve tried opening the MAX file directly in unity and also exported the FBX from 3DSM and they are both screwed up, it’s frustrating to say the least.

Can I ask a huuuuuge favour Eagle32 if it’s not too much trouble (or anyone else who wants a go), can you have a look at this 3DSM file and see where i’m going wrong? It’s only 2 boxes, but it’s still screwed up when I open it in unity, thanks a million.

416789–14457–$Boxtest.zip (15.9 KB)

The export process from Max is pretty fragile (it works but it’s easy to get the model in a messed up orientation or any number of other problems). The best advice I can give is that once you’ve figured out a process that works for you, write it down! Then make a checklist out of it to follow, it’s really easy to leave a step out or do something in the wrong order and have it mess the whole thing up.

I’m going to be fairly specific about everything I go through here, might be useful to other people as well. Feel free to skim over all the things you already know.

It won’t be making a difference to your orientation problem but your file’s units are in inches. If you have the units in meters then one meter in Max will be equal to one Unity unit which is the recommended scale in Unity. The FBX converter does convert to meters so scaling shouldn’t be an issue if you stay in inches, however, I like to take as many conversions and adjustments out of the process as possible.

Units can be changed in - Customize → Unit Setup…

Screenshots of my unit settings:

The orientation problem with the models in your attached file is because you’ve forgotten the 90 degree pivot rotation step. Here’s what I did to each of your boxes individually.

  1. Hierarchy → toggle Affect Pivot Only on.
  2. Move the pivot to where you want the mesh to rotate about.
  3. Hierarchy → toggle Affect Pivot Only off.
  4. *(see note below about this) Move the box to 0,0,0 (Note: in the series of screenshots here I skipped this step, in the attached files I did not skip it)
  5. With the box selected. Utilities → Reset XForm → Reset Selected

Before the next step take a look at the following picture. With the move tool selected and the front viewport active you can see in the perspective view the orientation you want the pivot to end up with.

  1. Hierarchy → toggle Affect Pivot Only on.

Now with Affect pivot only on we can see the pivots orientation and if we still have the move tool selected and the front view active; the orientation we want.

  1. Right click the Rotation tool. The Rotate Transform Type-In comes up. Rotations should all be 0.
  2. Change the Absolute:World → X to 90.0.

This is what it should look like now. Note that the orientation of the pivot gizmo matches that of the move gizmo from the previous image.

  1. Close the rotate type-in and Hierarchy → toggle Affect Pivot Only off.
  2. Export → Export Selected to fbx.

These are the export settings I use. Some of these are dependant on what I’m exporting like the animation frames.

Notes on export settings - I’m exporting to the older FBX200611 file version using the most recent exporter. You can probably use the latest file version fine. I’m still using this version because it works for me and I’m not in the habit of changing things that aren’t broken.

  1. Import the fbx into Unity. In this case the settings I changed in the FBXImporter settings in Unity are: scale to 1.0 (you always want to be able to import with 1.0 scale, scaling is frequently problematic and should be avoided whenever possible) and Animations → Generation to Do Not Import (their aren’t any animations).
  2. All done. The Transform for the model in Unity for the mesh is at this point
    Position 0,0,0 (assuming you performed step 4)
    Rotation 0,0,0
    Scale 1,1,1

I’ve attached the modified max file along with the exported FBX files and a Unity project with the meshes imported.

*Note - If you don’t move the mesh to 0,0,0 the Transform when imported into Unity will not be 0,0,0 because the pivot of the object wasn’t at 0,0,0 in max. This doesn’t really seem to matter because when you drop it in the scene you can set the transform to whatever you want and it doesn’t mess up the orientation like non-0,0,0 rotations do. However I usually have my models positioned at 0,0,0 in Max so they come into Unity with 0,0,0 position (if there are problems caused by not doing this I probably haven’t noticed them because I always do it).

417244–14468–$boxExport.zip (142 KB)

Eagle32, you are a legend, thanks a lot for explaining this, at the very least I think I owe you a beer :wink: I’ll have a look at following your tutorial when I get home from work later and let you know how things go.