Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 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 /
  • Help Room /
avatar image
0
Question by TonicMind · May 25, 2016 at 12:49 AM · rotationscripting problemclamped rotationadvanced

Need help clamping rotations to a range

So to start off this problem has existed for months, and I'm no closer to fixing it now than I was long ago.

I've got a GIF of the problem for you guys to watch:

via GIPHY

And video:

https://youtu.be/DERAhB6mih4

Anyway, the code I've written tries to clamp the angle to a range. I think the problem is with the SwivelGun.cs script. The problem? When the guns cross the X or Y screen axis they "spazz" out. Its unpredictable and impossible to really tell whats happening because it occurs so suddenly and at a quick rate.

My code: (SwivelGuns.cs)

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class SwivelGuns : MonoBehaviour
 {
     List<GameObject> barrels = new List<GameObject>(); //Refers to gun barrel objects
     List<GameObject> bases = new List<GameObject>(); //Refers to gun base objects
     List<GameObject> bulletSpawns = new List<GameObject>(); //Refers to barrel bullet spawn points
     List<GameObject> gunLookers = new List<GameObject>(); //Refers to the invisible (empty) game objects which look directly at the target whose rotations are used as a base to tell the guns where to aim.
     GunController shipsTarget; //I forgot
     public float xMin, xMax, yMin, yMax; //Range of rotation for these guns on which (local) axes
     public float angleDelta; //How fast they turn
     Gun[] gunScript; //Scripts attached to each gun. They do stuff. :P
 
     // Use this for initialization
     void Awake()
     {
         bases = GunController.getChildObjectsWithTag(gameObject, "GunBase");
         barrels = GunController.getChildObjectsWithTag(gameObject, "GunBarrel");
         bulletSpawns = GunController.getChildObjectsWithTag(gameObject, "BulletSpawn");
         gunScript = gameObject.GetComponentsInChildren<Gun>(); 
         gunLookers = GunController.getChildObjectsWithTag(gameObject, "GunLooker");
         shipsTarget = gameObject.GetComponentInParent<GunController>() as GunController;
         if(xMin < 0f) //If negative
         {
             xMin = 360f + xMin; //Fix to positive (at same unit circle position)
         }
 
         if (xMax > 360f) //If greater than one full circle
         {
             xMax -= 360f;
         }
         if (yMin < 0f) //If negative
         {
             yMin = 360f + yMin; //Fix to positive (at same unit circle position)
         }
 
         if (yMax > 360f) //If greater than one full circle
         {
             yMax -= 360f;
         }
     }
 
     public static float clampAngle (float ang, float min, float max)
     {   //Clamps the angle to the specified range! DOESN'T work perfectly
         bool angIsPositive = ang >= 0f && ang <= min;
         bool angIsNegative = ang >= max && ang <= 360f;
         if (angIsPositive)
         {
             return Mathf.Clamp(ang, 0f, min); //Clamp the angle to between zero and min
         } else if (angIsNegative)
         {
             return Mathf.Clamp(ang, max, 360f); //Clamp angle between max and 360
         } else //Outside of range!
         {
             print("Angle exceeded acceptable range!");
             return 0f;
         }
         
     }
 
     /*  OLD CODE      float n = Mathf.Round(ang / 360f); //Find how ang goes in to 360
            // print("Angle is: " +  ang); //ENABLE this code to see the bug.
             if (ang >= 360f || ang <= -360f)  //If above 360
             {
                 if (ang < 0f) //If negative
                 {
                     ang += n * 360f; //Add 
                 } else //If positive
                 {
                     ang -= (360f * n); //Force the value down to less than 360
                 }
 
               //  print("Angle was multiple of 360. Value is now: " + ang);
             }
 
             if (ang <= max && ang >= min) //If within the range of the min and max
             { 
                 return ang;
             } else
             {
                 //  print("BEFORE CHANGING ANGLE: "+ ang);
                 if (ang >= max)
                 {
                     ang = max;
                 }
                 else if (ang <= min)
                 {
                     ang = min;
                 } //If the angle value is further along than half way assign it the max value, otherwise give it the min.
                   // print("AFTER changing angle: " + ang);            
                 return ang;
             }*/
     // Update is called once per frame
     void Update()
     {
         swivelGuns();
     }
 
     void swivelGuns()
     {
         float x, y; //X and Y values may be different SIGNS for different gun mounting positions (but there are only four possible positions)
         Utilities.MOUNT_NORMAL gunNormal; //The MOUNT_NORMAL is an ENUM which specifies which way a given turret is mounted locally (UP, DOWN, LEFT, RIGHT)
         for (int i = 0; i != bulletSpawns.Count; i++) //Iterate through each gun changing its aim and stuff
         {
             gunNormal = gunScript[i].normal; //Get the normal for this gun
             bulletSpawns[i].transform.LookAt(shipsTarget.worldTarget);
             gunLookers[i].transform.LookAt(shipsTarget.worldTarget);
             x = gunLookers[i].transform.localEulerAngles.x; //X value here is up/down from camera's perspective!
             y = gunLookers[i].transform.localEulerAngles.y; //Y is left/right
 
           //print("Weapon: " + bulletSpawns[i].name  + "====" );
            // print("[A]  X= " + x + " Y= " + y);
             
 
             if (gunNormal == Utilities.MOUNT_NORMAL.UP)
             {
                // print("[--ATTN--] Aiming guns for upwards mount!");
                // print("[BEFORE] Value of x is: " + x + "Value of y is: " + y);
                 x = clampAngle(x, xMin, xMax);
                 y = clampAngle(y, yMin, yMax);
                 //print("[AFTER] Value of x is: " + x + "Value of y is: " + y);
                 bases[i].transform.localEulerAngles = Vector3.Slerp(bases[i].transform.localEulerAngles,
                                 new Vector3(0f, y, 0f), Time.deltaTime * angleDelta);
 
                 barrels[i].transform.localEulerAngles = Vector3.Slerp(barrels[i].transform.localEulerAngles,
                     new Vector3(x, 0f, 0f), Time.deltaTime * angleDelta);
             }
             else if (gunNormal == Utilities.MOUNT_NORMAL.RIGHT)
             {
              //   print("[ATTN] Aiming guns for rightwards mount!");
                 x = clampAngle(x, xMin, xMax);
                 y = clampAngle(y, yMin, yMax);
                 bases[i].transform.localEulerAngles = Vector3.Slerp(bases[i].transform.localEulerAngles,
                                                 new Vector3( 0f, y,0f), Time.deltaTime * angleDelta);
                 barrels[i].transform.localEulerAngles = Vector3.Slerp(barrels[i].transform.localEulerAngles,
                     new Vector3(x, 0f, 0f), Time.deltaTime * angleDelta);
             }
             else if (gunNormal == Utilities.MOUNT_NORMAL.LEFT)
             {
                // print("[ATTN] Aiming guns for leftwards mount!");
                 x = clampAngle(x, xMin, xMax);
                 y = clampAngle(-y, yMin, yMax);
                 bases[i].transform.localEulerAngles = Vector3.Slerp(bases[i].transform.localEulerAngles,
                                                                 new Vector3(0f, y, 0f), Time.deltaTime * angleDelta);
                 barrels[i].transform.localEulerAngles = Vector3.Slerp(barrels[i].transform.localEulerAngles,
                     new Vector3(x, 0f, 0f), Time.deltaTime * angleDelta);
             }
             else if (gunNormal == Utilities.MOUNT_NORMAL.DOWN)
             {
              //   print("[ATTN] Aiming guns for downwards mount!");
               //  print("[BEFORE] Value of x is: " + x + "Value of y is: " + y);
                 x = clampAngle(-x, xMin, xMax);
                 y = clampAngle(-y, yMin, yMax);
               //  print("[AFTER] Value of x is: " + x + "Value of y is: " + y);
                 bases[i].transform.localEulerAngles = Vector3.Slerp(bases[i].transform.localEulerAngles,
                                                 new Vector3(0f, y, 0f), Time.deltaTime * angleDelta);
                 barrels[i].transform.localEulerAngles = Vector3.Slerp(barrels[i].transform.localEulerAngles,
                     new Vector3(x, 0f, 0f), Time.deltaTime * angleDelta);
             }
          // print("[B] X= " + x + " Y= " + y);
 
         }
     }
 }


The only gun normals in use in this particular ship configuration are UP and DOWN.

If you need more information, please ask.

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 TonicMind · May 25, 2016 at 12:53 AM 0
Share

I believe the problem occurs when the guns are pointed "straight" ahead. I mean that is when they are at or close to zero. On the unit circle zero is essentially 360 degrees, which makes me believe they're getting reset to either of those values any time they reach that position.

avatar image Owen-Reynolds · May 25, 2016 at 01:40 AM 0
Share

Hard to tell, but: a common problem is you can't set the rotation, and then read eulerAngles. If you want to directly monitor x,y,z rotation, keep them as global floats, change them directly, and use them only to set rotation -- never read them back.

The problem is a rotation has more than one legal eulerAngles. It won't always give you back the same numbers x,y,z you used to set it.

avatar image TonicMind Owen-Reynolds · May 25, 2016 at 10:38 PM 0
Share

Hey I found a way to at least get the spazmatic behavior of my guns to be prevented, though clamping the rotations seems to be above my head at the moment.

I'm pretty proud of it too. I managed to solve the turret ai$$anonymous$$g problem without copying select values from other objects and assigning them, ins$$anonymous$$d I do some simple but specific trigonometry to program where the guns ought to aim! Its a problem I never thought I'd be good enough to solve.

avatar image TonicMind · May 25, 2016 at 03:58 PM 0
Share

Yeah I kinda figured that was the case in one way or another.

Is there ANY way to do this though? I just need to make the guns restricted to a range of angles.

0 Replies

· Add your reply
  • Sort: 

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

61 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 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 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 avatar image

Related Questions

Object don't rotate correctly 1 Answer

following and rotation help 0 Answers

.rotation doesn't seem to work, can't shoot projectile at mouse coordinates 0 Answers

Orbit object around parent object 1 Answer

Searching a function to get the rotation of one Vector3 in relation to another 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