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 /
avatar image
0
Question by Claite · Oct 09, 2015 at 02:00 PM · script.controlseulerflightlocal axis

Flight control without torque/force

The goal:

No physics flying object rotating around it's local z and x axis based on joystick input. So if I pull back, it goes back by a fixed angle. If I push right, it rolls right by fixed angle increments. I don't want to use forces since I want the controls to feel very "tight" without having to counteract all the forces to straighten out the object.


The problem:

I can get it to work along their independent axis. If I push only right at the start, it rotates correctly. If I push only back, it does it correctly. When I start combining the two (doing a bank turn for example) it all goes wack.

I've been hammering away for a while trying to get this to work right, but it just doesn't seem to want to work as expected. For some reason when the transform's "forward" is no longer along the z plane, pulling back has very different behavior than just pulling back. Gifs for reference (you'll note in the second gif, I get off the x and z plane, and when pulling straight back or forward, left or right (values at bottom left of recording) the square moves completely off axis.):

Regular single-axis movements

Irregular movements when two axis are combined


The code:

   public Rigidbody body;
   public int SPEED = 20;
   public float tiltAngle = .5f;
   public Text debugText;
 
   private float previousX;
   private float previousY;
   private float previousZ;
 
 ....
 
 void FixedUpdate() {
     Vector3 forward = body.transform.forward;
     Vector3 right = body.transform.right;
     // static forward movement (working fine)
     body.velocity = new Vector3(SPEED * forward.x, SPEED * forward.y, SPEED * forward.z);
     // Inverse tilt angle so it matches with roll left - left on thumbstick
     float tiltAroundZ = Input.GetAxis("Horizontal") * -tiltAngle;
     float tiltAroundX = Input.GetAxis("Vertical") * tiltAngle;
     // Modifying tilt around axis to be relative to transforms local axis by
     // using it's identity vectors. Likely where the issue is.
     previousX += (tiltAroundX * right.x) + (tiltAroundZ * forward.x);
     previousY += (tiltAroundX * right.y) + (tiltAroundZ * forward.y);
     previousZ += (tiltAroundX * right.z) + (tiltAroundZ * forward.z);
     Quaternion target = Quaternion.Euler(previousX, previousY, previousZ);
     // Removed slerp since I felt the imprecision might build up from it's actual position
     // and the previous x/y/z. Am I wrong in this assumption?
     transform.rotation = target;
   }

Comment
Add comment · Show 3
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 meat5000 ♦ · Oct 09, 2015 at 10:48 AM 0
Share

Looks fine to me. Your links are both he same.

avatar image Claite meat5000 ♦ · Oct 09, 2015 at 05:42 PM 0
Share

Oh shoot, and now I'm not at my computer that has the other image. I'll try to update it tonight.

avatar image Claite meat5000 ♦ · Oct 10, 2015 at 05:09 AM 0
Share

Update the image, sorry for the mistake.

2 Replies

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

Answer by Claite · Oct 14, 2015 at 09:48 AM

Alright, for posterity here's what I eventually settled on. Quaternions weren't working, and I think it's because I kept hitting the gimbal lock problem since my math is bad.

I turned to torque like I had originally ignored, but to get the behavior I want, I reset angular velocity back to 0 every frame. This gives me the sharp start and stop rotation around the appropriate axis without the constant rolling of using forces.

Here's the working code:

 void FixedUpdate() {
     Vector3 forward = body.transform.forward;
     Vector3 right = body.transform.right;
 
     body.velocity = new Vector3(SPEED * forward.x, SPEED * forward.y, SPEED * forward.z);
     float tiltAroundZ = Input.GetAxis("Roll") * -tiltAngle;
     float tiltAroundY = Input.GetAxis("Horizontal") * tiltAngle;
     float tiltAroundX = Input.GetAxis("Vertical") * tiltAngle;
 
     body.angularVelocity = Vector3.zero;
 
     body.AddRelativeTorque(tiltAroundX, tiltAroundY, tiltAroundZ);
   }


No more needing to save values from previous frames. Thanks for the help.

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 FortisVenaliter · Oct 09, 2015 at 02:36 PM

Okay, so for full rotation around all three axes, you're going to need a more elegant solution than euler angles.

What I would recommend is to use the euler angles to make a quaternion for DELTA rotation, or change in rotation. Then simply multiply that on top of your existing rotation quaternion.

So, basically, you want to keep your rotation stored as a quaternion, rather than component euler floats.

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 Claite · Oct 09, 2015 at 05:50 PM 0
Share

Just read up on quaternion multiplication and this seems like it'll be the right answer. From a quick search:

The multiplication of quaternions represents composing the two rotations: perform one rotation and then perform the other one.

reference

Since I'm not at the appropriate computer right computer right now, I won't be able to verify till tonight, but will accept this answer if all goes as expected.

avatar image Claite · Oct 10, 2015 at 05:07 AM 0
Share

Ok, after working through this, it didn't seem to work. Here's what I had tried:

 private Quaternion previous;
 void FixedUpdate() {
      Vector3 forward = body.transform.forward;
      Vector3 right = body.transform.right;
      body.velocity = new Vector3(SPEED * forward.x, SPEED * forward.y, SPEED * forward.z);
      float tiltAroundZ = Input.GetAxis("Horizontal") * -tiltAngle;
      float tiltAroundX = Input.GetAxis("Vertical") * tiltAngle;
      float deltaX = (tiltAroundX * right.x) + (tiltAroundZ * forward.x);
      float deltaY  = (tiltAroundX * right.y) + (tiltAroundZ * forward.y);
      float deltaZ = (tiltAroundX * right.z) + (tiltAroundZ * forward.z);
      Quaternion target = Quaternion.Euler(deltaX, deltaY, deltaZ);
      if (previous != null) {
        target = previous * target;
        previous = target;
      }
 
      transform.rotation = target;
 }


Unfortunately, this didn't move the object at all. With several prints, I noticed it was trying to rotate by about 6 degrees, but that's it. I want the object to continue rotating around the axis, so I believe I need incrementing values. The multiplication doesn't seem to be additive, so here's what happens:

previous = (10, 0, 0, 1) target = (10, 0, 0, 1) previous * target = rotate to 10 on x axis, then rotate to 10 on x axis (already there)

So it just rotates to 10. I want it to rotate to 20, which my old code does correctly. The issue is when my deltas for pulling back aren't along the respective planes like (10, 0 ,0) but ins$$anonymous$$d at some off angle like (5, 2, 4) or something.

Thoughts?

Edit: Here is the correct gif of showing the awkward behavior: imgur

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

How to change controls in-game? 0 Answers

Dampen Flight Controls 1 Answer

Boat's rotation in relation to the rudder 1 Answer

Spaceship Control Help 2 Answers

How to check rigid body vector movement? 0 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