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 BritishGuy · Jan 12, 2014 at 10:13 PM · rotationobjectanglelimitdegrees

Limit Object Angle

Hello,

I am not sure how to limit an objects degree of angle in my case 25 degrees up & 15 degrees down, Is there anyway for it to be implemented into this script?

 var goTarget : GameObject;
 var maxDegreesPerSecond : float = 60.0;
 private var qTo : Quaternion;
  
 function Start () {
     qTo = goTarget.transform.localRotation;
 }
  
 function Update () {
     var v3T = goTarget.transform.position - transform.position;
     var v3Aim : Vector3;
     v3Aim.x = 0.0;
     v3Aim.y = v3T.y;
     v3T.y = 0.0;
     v3Aim.z = v3T.magnitude;
     qTo = Quaternion.LookRotation(v3Aim, Vector3.up);
     transform.localRotation = Quaternion.RotateTowards(transform.localRotation, qTo, maxDegreesPerSecond * Time.deltaTime);
 }

I have tried a few things but i just get errors popping up left right center, Any help would be greatly appreciated, Thanks.

Comment
Add comment · Show 4
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 getyour411 · Jan 12, 2014 at 10:16 PM 0
Share

See if this helps: http://docs.unity3d.com/Documentation/ScriptReference/$$anonymous$$athf.Clamp.html

avatar image BritishGuy · Jan 12, 2014 at 10:32 PM 0
Share

@getyour411

Thanks for the reply, I implemented the $$anonymous$$athf.Clamp on the rotation but its not having any effect, $$anonymous$$aybe i am putting it in the wrong place or i am using the wrong code.

 transform.rotation.x = $$anonymous$$athf.Clamp(transform.rotation.x, -15, 25);
avatar image BritishGuy · Jan 12, 2014 at 11:57 PM 0
Share

Any Ideas please?

avatar image Quillicit · Jan 13, 2014 at 08:58 AM 0
Share

Ins$$anonymous$$d of using Quaternion.RotateTowards(), try Quaternion.Euler(). This will require some other modification of your script, but I had the same problem once upon a time and this is how I solved it.

2 Replies

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

Answer by robertbu · Jan 13, 2014 at 11:36 AM

Note when posting questions like this one and using code borrowed from another question, please make a reference to the original code. This 1) helps other such as @aldonaletto have the full context for an answer, 2) gives credit to the original author, and 3) makes it more likely that the original author will recognize the code and give you an answer. In this case, you borrowed the code from my answer here:

http://answers.unity3d.com/questions/388185/make-the-turret-automatically-rotate-to-look-at-wh.html

Note this code only works if you keep the turret parallel to the XZ plane. So if your tank is roaming over hills, you will need a different solution. As for limiting rotation, you can do it this way:

 #pragma strict
 
 var goTarget : GameObject;
 var maxDegreesPerSecond : float = 30.0;
 
 var maxDegrees = 25.0;
 var minDegrees = -15.0;
 
 private var qTo : Quaternion;
  
 function Start () {
     qTo = goTarget.transform.localRotation;
 }
  
 function Update () {
     var v3T = goTarget.transform.position - transform.position;
     var v3Aim : Vector3;
     v3Aim.x = 0.0;
     v3Aim.y = v3T.y;
     v3T.y = 0.0;
     v3Aim.z = v3T.magnitude;
     
     var angle = Mathf.Atan2(v3Aim.y, v3Aim.z) * Mathf.Rad2Deg;
     
     if (angle > maxDegrees) {
         v3Aim.y = Mathf.Tan(maxDegrees * Mathf.Deg2Rad) * v3Aim.z; 
     }
     
     if (angle < minDegrees) {
         v3Aim.y = Mathf.Tan(minDegrees * Mathf.Deg2Rad) * v3Aim.z;
     }
     
     qTo = Quaternion.LookRotation(v3Aim);
     transform.localRotation = Quaternion.RotateTowards(transform.localRotation, qTo, maxDegreesPerSecond * Time.deltaTime);
 }

The idea is that if the angle of the target is outside of your range, the 'y' value of the 'v3Aim' is recalculated to bring it up or down so that the angle is within range.

Comment
Add comment · Show 5 · 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 BritishGuy · Jan 13, 2014 at 11:58 AM 0
Share

Sorry i will keep that in $$anonymous$$d next time, Your modification works wonders but then i am back to facing the issue of the gun not looking at the goTarget when i am on any degree of slope, Thanks.

avatar image robertbu · Jan 13, 2014 at 12:31 PM 0
Share

Here is a simpler solution to the problem you ask here:

 #pragma strict
 
 var goTarget : GameObject;
 var maxDegreesPerSecond : float = 30.0;
 
 var maxDegrees = 25.0;
 var $$anonymous$$Degrees = -15.0;
 
 private var qTo : Quaternion;
  
 function Start () {
     qTo = goTarget.transform.localRotation;
 }
  
 function Update () {
     var v3T = goTarget.transform.position - transform.position;
     var v3Aim : Vector3;
     
     var y = v3T.y;
     v3T.y = 0.0;
     var angle = $$anonymous$$athf.Atan2(y, v3T.magnitude) * $$anonymous$$athf.Rad2Deg;
     angle = $$anonymous$$athf.Clamp(angle, $$anonymous$$Degrees, maxDegrees); 
     
     qTo = Quaternion.AngleAxis(-angle, Vector3.right);
     transform.localRotation = Quaternion.RotateTowards(transform.localRotation, qTo, maxDegreesPerSecond * Time.deltaTime);
 }
avatar image robertbu · Jan 13, 2014 at 12:42 PM 0
Share

Here is a script that will handle a tank running over hills. Unlike the original scripts, this is an all-in-one script for both the turret and the gun. Currently it does limit the guns elevation, but not in the way you ask for here. Essentially when the target is out of range (above or below), it just doesn't change the elevation of the gun. It also defines the range a bit differently. You specify a maximum angle from the starting angle of the gun. So for example in your case where you want 25 up and 15 down, you would start with the gun elevated 5 degrees and specify 20 as the 'maxGunAngle'. This code could be rewritten to handle an explicit $$anonymous$$/max values as I've done in the scripts above, but I don't have time right now to make the changes. The technique to make the change would be similar to either of the two ways I've changed the scripts above.

 #pragma strict
 
 var target : Transform;
 var gun : Transform;
 var turretDegreesPerSecond : float = 45.0;
 var gunDegreesPerSecond : float = 45.0;
 
 var maxGunAngle = 45.0;
 
 private var qTurret : Quaternion;
 private var qGun : Quaternion;
 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;
 
     qTurret = Quaternion.LookRotation(planePoint - trans.position, transform.up);
     transform.rotation = Quaternion.RotateTowards(transform.rotation, qTurret, turretDegreesPerSecond * Time.deltaTime);
 
     var v3 = Vector3(0.0, distanceToPlane, (planePoint - transform.position).magnitude);
     qGun = 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");
 }
avatar image aldonaletto · Jan 13, 2014 at 01:11 PM 1
Share

Aha,I suspected that the code was out of context! So you flatten the direction vector onto the plane YZ and calculate the elevation angle, clamp it to the range and calculate the clamped direction vector. I suppose that in this case localRotation will work fine with the value returned from LookRotation (provided that the turret is aligned to Y)

avatar image BritishGuy · Jan 13, 2014 at 01:19 PM 0
Share

You sir are a legend, It surprisingly works better than i had intended, Thanks for the help guys much appreciated.

avatar image
1

Answer by aldonaletto · Jan 13, 2014 at 10:29 AM

This code won't work: you're messing localRotation with global rotation, and the Vector3 math that calculates v3Aim doesn't seem to produce something useful.

Limiting rotation angles is a complex job: you can't rely on the Euler angles because at certain sectors they can switch to weird (although correct) combinations.

A possible solution is to decompose the desired direction into vertical and horizontal components, limit the vertical direction and join them into a limited direction vector - like this:

 var maxAngle: float = 25;
 var minAngle: float = -15;
 
 function Update () {
   // get the normalized target direction:
   var dir = (goTarget.transform.position - transform.position).normalized;
   var maxSin = Mathf.Sin(maxAngle * Mathf.Deg2Rad); // get sine of max angle
   var minSin = Mathf.Sin(minAngle * Mathf.Deg2Rad); // get sine of min angle
   var sine = Mathf.Clamp(dir.y, minSin, maxSin); // get the clamped angle sine
   var cos = Mathf.Sqrt(1 - (sine * sine)); // calculate the cosine with Pythagoras
   // compound the new direction vector:
   dir = Vector3(dir.x, 0, dir.z).normalized * cos; // set the horizontal direction...
   dir.y = sine; // and set the vertical component
   qTo = Quaternion.LookRotation(dir, Vector3.up); // look at the new direction
   transform.rotation = Quaternion.RotateTowards(transform.rotation, qTo, maxDegreesPerSecond * Time.deltaTime);
 }

Notice that this code takes advantage of the fact that in a normalized vector the Y component is numerically equal to the sine of the elevation angle: we can limit it to the desired range and create a new direction vector.

Comment
Add comment · Show 1 · 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 BritishGuy · Jan 13, 2014 at 11:05 AM 0
Share

That beautiful script would be perfect if it was on a single turret, $$anonymous$$y script was intended for a barrel of a tank for vertical elevation, I have a separate script for the turret of the tank to only rotate on the Y axis, Sorry its my fault for not being specific enough, Your script would be perfect if it only it rotated on the X axis and not all axis, Thanks for Reply.

Tank Hierarchy

 Tank
   Turret //rotates on y axis
       Gun // rotates on x axis

The turret works as intended, Its the Gun that's bothering me.

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

20 People are following this question.

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

Related Questions

0-360 Y degree from Vector3.Angle 1 Answer

90 degrees isnt? 2 Answers

Rotating A Character 180 Degress 1 Answer

How do I limit the vertical rotation of a camera? 0 Answers

how to convert rotation of an object in degrees X 2 Answers


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