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 NosVidz · Mar 28, 2016 at 12:28 AM · rotationscript.vector3floataccuracy

Accuracy issues with Float (Vector3)

Hi.

I wrote an NPC movement script, which includes the rotation of the NPC-character in order to make it look forwards after changing its direction. It works like follows: After the movement to a certain point, it the NPC turns around until the correct rotation is reached, and then starts moving.

The problem is that it sometimes get stuck at rotating. Obviously this is caused by the floating point inaccuracy. I checked that by printing the result of the == opertion where I compare the normalized vectors, and it returns false. I also printed the values of the vectors to see how big the inaccuracy is:

(0.9831, 0.0000, 0.1830) (0.9824, 0.0000, 0.1866)

I know that the == operator has approximation integrated, so I am quite astonished that this simple rotation already causes problems.

Are there any ways to prevent this (globally or in that special case). I honestly don't even know if the script does a good job, I started with unity a few days ago. Any advice would be appreciated.

Edit: Here the complete code. Nothing is accessed by other scripts.

 [RequireComponent(typeof(Animator))]
 public class Patrol : MonoBehaviour {
     public Transform[] patrolPoints;
     private Transform current;
     private int currentPoint = 0;
     public float moveSpeed;
     public float animSpeed = 1.5f;
     private Animator anim;
 
     [Range(0,360)]
     public float rotationSpeed;
 
     void Start () {
         transform.position = patrolPoints[currentPoint].position;
         current = patrolPoints[currentPoint];
         anim = gameObject.GetComponent<Animator>();
         anim.speed = animSpeed;
         anim.SetFloat("Speed", moveSpeed);
     }
 
     private bool rotating = false;
     void Update() {
         if (equals(transform.position,current.position))
         {
             currentPoint = (currentPoint + 1) % patrolPoints.Length;
             current = patrolPoints[currentPoint];
             rotating = true;
         }
 
         if (!rotating)
         {
             transform.position = Vector3.MoveTowards(transform.position, current.position, moveSpeed * Time.deltaTime);
         }
         else {
             Vector3 targetDir = current.position- transform.position ;
             transform.rotation = Quaternion.LookRotation(Vector3.RotateTowards(
                transform.forward, 
                targetDir, rotationSpeed*Time.deltaTime, 0));
             if (equals(targetDir.normalized, transform.forward.normalized))
             {
                 rotating = false;
             }
         }
     }

 
Comment
Add comment · Show 1
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 elenzil · Mar 31, 2016 at 07:09 PM 0
Share

you're saying that modifying the transform.forward value is also modifying the transform.position ? that does seem weird. can you make a $$anonymous$$imal repro of that ?

for what it's worth, i often use a utility function of my own: bool isWithinEpsilon(float a, float b, float epsilon = 0.0001f) { float diff = b - a; return ((-epsilon < b) && (b < epsilon)); }

2 Replies

· Add your reply
  • Sort: 
avatar image
2

Answer by Zeoli · Mar 28, 2016 at 06:19 AM

I believe you may need to mess around with this Mathf function. http://docs.unity3d.com/ScriptReference/Mathf.Approximately.html

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 NosVidz · Mar 31, 2016 at 06:16 PM 0
Share

I didn't know about the Approximately-function, thanks. But that is not enough. Comparing (0.9832, 0.0000, 0.1827), (0.9824, 0.0000, 0.1866) returns false for the z-values, which are 0.0039 apart. I guess I have to compare it manually then?

avatar image Cherno NosVidz · Mar 31, 2016 at 06:43 PM 0
Share

You can also try using the $$anonymous$$ath.Round method (using System). Note that it's not $$anonymous$$ath*f*.Round. $$anonymous$$ath.Round accepts an int parameter to pass the desired number of decimal places that should be rounded to.

avatar image
1

Answer by phxvyper · Mar 31, 2016 at 07:20 PM

You've been misinformed. The == operator is an equality operator and does not have any checks for approximation. This is why Mathf.Approximately exists.

Personally, I believe there's something in your code for rotation or movement that you can change in order to fix this issue. However, what you can do is create your own form of Approximately, like I do on occasion:

 public bool Approximately(float a, float b, float epsilon)
 {
     return (Mathf.Abs(a - b) < epsilon) || (Mathf.Approximately(Mathf.Abs(a - b), epsilon));
 }
 
 //or JS:
 
 function Approximately(a : float, b : float, epsilon : float) : float
 {
     return (Mathf.Abs(a - b) < epsilon) || (Mathf.Approximately(Mathf.Abs(a - b), epsilon));
 }

epsilon is the maximum distance between two floats that you'll accept as approximately.

 Approximately(0.05f, 0.1f, 0.05f) //will return true
 Approximately(0.06f, 0.1f, 0.04f) //will return true
 Approximately(0.05f, 0.1f, 0.06f) //will return false

Comment
Add comment · Show 4 · 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 Bunny83 · Mar 31, 2016 at 08:06 PM 1
Share

Actually the Vector3 equality operator does some approximation. It's implemented like this:

 public static bool operator ==(Vector3 lhs, Vector3 rhs)
 {
     return Vector3.Sqr$$anonymous$$agnitude(lhs - rhs) < 9.99999944E-11f;
 }

The question was about comparing Vector3 values, not float values. However the error is way beyond most approximation limits. When dealing with vectors you never really compare two vectors directly. You usually check the distance between them against an epsilon value.

When using Sqr$$anonymous$$agnitude keep in $$anonymous$$d to square the epsilon as well. So if the distance between the vectors should be lower than 0.01f you have to compare against (0.01f² == 0.0001f). Sqr$$anonymous$$agnitude is a bit faster to calculate than magnitude as it doesn't require a square root.

avatar image phxvyper Bunny83 · Apr 01, 2016 at 05:21 AM 0
Share

Oh i thought he was talking about directly comparing floats, not Vectors. Whoops!

avatar image NosVidz · Apr 01, 2016 at 05:12 AM 0
Share

Personally, I believe there's something in your code for rotation or movement that you can change in order to fix this issue.

I edited the post and provided the full code, perhaps you can find something.

avatar image phxvyper NosVidz · Apr 01, 2016 at 05:23 AM 1
Share

Have you tried Slerp'ing the rotation ins$$anonymous$$d of using RotateTowards?

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

7 People are following this question.

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

Related Questions

How can I replace this Vector3 with a float? 2 Answers

Calculating Scrolling GameObject x position scrolling pass another GameObject x postion (2D Game) 1 Answer

Velocity value changes way to drastically when position quickly changes 0 Answers

Android Gyroscope inaccuracy problems. 1 Answer

problem with object rotation 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