Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Epitaph778 · Sep 24, 2014 at 01:18 AM · rotationaxisturret

Turret Rotation on a moving object with rotation limits

I've been working at a problem with some time, and a week+ of googling and experimenting has got me nowhere.

--THE PROBLEM--

I have a turret on a moving object (let's say, for the sake of simplicity, it's on a tank).

Now the turret faces the mouse position with limitations:

  1. It cannot rotate left or right so that the angle is in excess of variable maxLRArc/2.

  2. It is limited in L/R rotation speed by rotationSpeedLR

  3. It cannot rotate up or down so that the angle is in excess of variable maxUDArc/2.

  4. It is limited in U/D rotation speed by rotationSpeedUD

Here's a picture for clarity:

alt text

EDIT: A picture of the scene in Unity:

alt text

  • The YELLOW line is the raytrace from camera to mouse position

  • The CYAN lines form the limits of the Up/Down rotation

  • The RED (less visible) lines form the limits of the Left/Right rotation

  • The BLUE line is the mouse position projected on the L/R plane

  • The MAGENTA line is the mouse position projected on the U/D plane

  • The GREEN line shows the parent's forward vector from the position of the turret

If it's still unclear you can think about it as having someone's head track a moving object... The angle limitations are apparent in that scenario... but the person can only turn his head left or right and pitch up or down, but not tilt his head to one side or another.

--THE APPROACH--

I've been attempting to approach the problem from a step-by-step method, which is to say:

  1. Turret first rotates left or right towards the mouse.

  2. Turret then rotates up or down towards the mouse.

The way I'm doing is is first projecting the mouse position vector onto a plane in-line with the turret. Once for each step of the rotation, so that the mouse position is in-plane with the step's angle limits.

The checks and balances all work beautifully, the problem is executing the rotations, WITH a constant speed.

When I attempted to rotate for each axis separately, the rotations interfered with one another. When I attempted to rotate them together, the turret ended up twisting along the local Z axis (separating from it's logical point-of-contact to the tank) particularly noticeable when the tank goes up or down an incline.

--THE PLEA--

I've tried a lot of solutions that I've found but none give the desired results. Most (if not all) deal with a few of the restrictions I've listed individually, but not together like this.

I figure I'm at the limits of my capability and need to yield to more experienced individuals. Any help is greatly appreciated!

EDIT: The code I have is so messy and fragmented that it would be more harm than good, but if necessary, i can provide it.

tankproblem.jpg (105.6 kB)
Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Epitaph778 · Oct 07, 2014 at 01:39 AM

After attempting the solutions in the answers provided, I eventually came upon a working solution.

Since the code was functional for turn movement and pitch movement individually, I calculated the proper quaternions for the movement within the boundaries, then converted portions of these quaternions to vector3s of euler angles and used quaternion.euler to rotate:

 Vector3 rot = new Vector3(pitchQuat.eulerAngles.x,
                   turnQuat.rotation.eulerAngles.y,
                   pitchQuat.rotation.eulerAngles.z);
 transform.rotation = Quaternion.Euler(rot);


Thanks for all the responses everyone!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by robertbu · Sep 24, 2014 at 02:31 AM

Here is a script that gets you most of the way there. There some unknowns in your question, so I expect you'll have a few changes, but I believe all the heavy lifting is done.

 #pragma strict
 
 var target : Transform;
 var gun : Transform;
 var turretDegreesPerSecond : float = 45.0;
 var gunDegreesPerSecond : float = 45.0;
 
 var maxGunAngle = 45.0;
 var maxTurretAngle = 45.0;
 
 
 private var qGunStart : Quaternion;
 private var trans : Transform;
 
 function Start() {
     trans = transform;    
     qGunStart = gun.transform.localRotation;
 }
 
 function Update () {
     var distanceToPlane = Vector3.Dot(trans.up, target.position - trans.position);
     var planePoint = target.position - trans.up * distanceToPlane;
     
     var qTurret : Quaternion = Quaternion.LookRotation(planePoint - trans.position, transform.up);
     var qForward : Quaternion = Quaternion.LookRotation(transform.parent.forward);
     if (Quaternion.Angle(qTurret, qForward) < maxTurretAngle) {
         transform.rotation = Quaternion.RotateTowards(transform.rotation, qTurret, turretDegreesPerSecond * Time.deltaTime);
     }
     else {
         Debug.Log("Target beyond turret range");
     }
     
     var v3 = Vector3(0.0, distanceToPlane, (planePoint - transform.position).magnitude);
     var qGun : Quaternion = Quaternion.LookRotation(v3);
     
     if (Quaternion.Angle(qGunStart, qGun) <= maxGunAngle)
         gun.localRotation = Quaternion.RotateTowards(gun.localRotation, qGun, gunDegreesPerSecond * Time.deltaTime);
     else
         Debug.Log("Target beyond gun range");
 }

And here is a unitypackage with this script in use:

www.laughingloops.com/Turret2.unitypackage

Note that maxGunAngle() will define the maximum delta from the start position of the gun. For maxTurretAngle, the maximum angle is between the forward of the parent object and the gun.

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Epitaph778 · Sep 24, 2014 at 03:40 PM 0
Share

Hey, thanks for your response! I've tried out the script and it works, though not in the manner I'm looking for.

I'm trying to figure out a means of rotation for the gun IS the turret. there are no separate object. You can think of it as a rocket turret or as my initial analogy (provided above) stated: someone's head tracking an object without twist.

I also forgot to mention, that the gun should always track the target, but stop at a maximum range. In a two-step rotation process should perform correctly. Again, similar to head tracking in games. If you are running around a character, and you run past their head range behind that character's head, the head will track you to an extent, and when you pass directly behind the character, the head will turn the other way and stop at the other extent until you come into range again.

avatar image robertbu · Sep 24, 2014 at 06:59 PM 0
Share

I think this will get you what you want, or at least a step closer. There is just one angle limit, so the limit will be a circle...or you can think about it as a cone-shaped possible area for targets. So it will perform similar to a head rotation.

 #pragma strict
 
 public var target : Transform;
 public var maxAngle : float = 35.0;
 public var speed : float = 55.0;
 
 function Update () {
     var v3Target = (target.position - transform.position);
     var v3Forward = transform.parent.forward;
     if (Vector3.Angle(v3Target, v3Forward) > maxAngle) {
         var v3Axis = Vector3.Cross(v3Forward, v3Target);
         v3Target = Quaternion.AngleAxis(maxAngle, v3Axis) * v3Forward;
         Debug.Log("Rotation limited");
     }
     
     var qTarget = Quaternion.LookRotation(v3Target);
     transform.rotation = Quaternion.Slerp(transform.rotation, qTarget, Time.deltaTime * speed);
 }

The maxAngle is from the forward of the parent, so the angle of view will be twice this angle.

avatar image
0

Answer by sevensixtytwo · Sep 24, 2014 at 04:45 PM

You can use just one segment of code from robertbu's answer. Here:

 var toTarget : Quaternion = Quaternion.LookRotation(target.position - turret.position, turret.up);
 transform.rotation = Quaternion.RotateTowards(transform.rotation, toTarget, turretSpeed * Time.deltaTime);
 //freeze Z-axis to stop turret from rolling
 transform.localRotation.z = Quaternion.identity.z;

With these alone, the turret will rotate towards the target on all axes, except Z.

Use the ClampAngle function specified in aldonaletto's answer here:

Limit Local Rotation

It automatically converts negative values into usable eulers. Of course, you'll need minimum and maximum values for your X and Y axes. Use it like this:

 var angleX = ClampAngle(turret.localEulerAngles.y,minX,maxX);
 var angleY = ClampAngle(turret.localEulerAngles.x,minY,maxY);
 
 turret.localEulerAngles = new Vector3(angleY,angleX,turret.localEulerAngles.z);

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Constraining turret rotation in local space 1 Answer

How to rotate cannon by angles on top of a turret 1 Answer

TurretRotation on a starship (full 3d) 3 Answers

Input.acceleration Y and Z are the same? 1 Answer

different axis for different objects? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges