• 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 MrZalib · May 09, 2013 at 01:19 PM · translateframe rate

Constant rate of Translate

I've noticed that translate does not apply each frame at regular constant intervals. For example under my current script and "speed" I have an object that moves roughly .2 in whatever direction it happens to be set at. When I say roughly I mean it may be .2 for the first four frames but the fifth frame would be 1.9999 or something similar.

My question is, is there any way to guarantee that it will be .2 every frame?

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

1 Reply

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

Answer by robertbu · May 09, 2013 at 01:28 PM

Floating number are imprecise, so no you cannot guarantee .2 every frame. Plus, the time taken each frame will vary (if you are using Update()), so even if you do get .2, your motion will not be smooth under any kind of load situation.

With that said, you might be able to get a more precise result if you calculate an absolute move each frame rather than many relative moves:

 public var v3Step = Vector3(0.1, 0.0, 0.1);
 private var v3Start : Vector3;
 private var iFrame = 0;
  
 function Start () {
  v3Start = transform.position;
 }
  
 function FixedUpdate () {
     iFrame++;
     transform.position = v3Start + iFrame * v3Step; 
 } 

 
Comment
Add comment · Show 7 · 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 MrZalib · May 09, 2013 at 01:54 PM 0
Share

Alright, I think I get what's going on here, could you explain how keeping a count of the frames is needed?

Also perhaps more insight to my problem might better lead me to a solution.

Here's what I'm doing. For simplicity's sake I will use an example of two spheres. One is being controlled by the player, the other will be following. Now my logic to follow is as follows:

When a directional key is pressed, player controlled sphere will store it's position in a Vector. The other sphere will continue to move until it meets this point. As you said floating points aren't accurate enough so I use a margin of say .05 and check against that. When the other sphere comes within the margin it changes direction to whatever the player choose and moves that way until the next point is recorded and checked against.

Here's my problem with this, because floats are inaccurate enough to where I need the margin big enough to compensate for all possible values, I end up with situations where the other sphere will turn to quickly or it will over shoot the margin and never turn. Thus shattering my illusion that the other sphere is following the player controlled sphere at a fixed distance.

Is there any way to solve this? Or do you think I should think of a different method to have the other ball 'follow' the player controlled ball?

avatar image robertbu · May 09, 2013 at 02:20 PM 1
Share

There are lots of ways to solve this problem. If you post your code I can provide a more targeted solution. But my first suggestion is to use Vector3.$$anonymous$$oveTowards() to move your "follower." Say v3Next is a Vector3 is the follower's next target position. This code would go into Update():

 transform.position = Vector3.$$anonymous$$oveTowards(transform.position, v3Next, distPerSecond * Time.deltaTime);

 if (transform.position == v3Next) {
    // Do whatever to reset v3Next to a new value
 }

'distPerSecond' is a variable set to the max distance you want the follower to travel per second.

Oh, to answer your question about the frame count, imagine you measured a room with a one inch measure. You would need to move the measure many times perhaps with a bit of error each time. Errors could compound creating a large final error. If measured the room all at once with a longer tape, the possible error goes down. This code is like taking the tape measure and increase its length by one inch, and then moving the object to the end of the measure. By multiplying by the frames, I'm calculating the total offset that should happen for that frame based on the original position. Given your followup information about what you are trying to do, I don't recommend trying to solve your problem using this solution.

avatar image MrZalib · May 09, 2013 at 03:33 PM 0
Share
 using UnityEngine;
 using System.Collections;
 
 public class BodyController : $$anonymous$$onoBehaviour 
 {
     public int direction = 1;
     public float $$anonymous$$ARGIN = 0.070f;
     
     
     PlayerControl playerControl;
     
     // Use this for initialization
     void Start() 
     {
         playerControl = GameObject.FindWithTag("Player").GetComponent<PlayerControl>();
         direction = playerControl.direction;
     }
     
     // Update is called once per frame
     void Update() 
     {
         
         //$$anonymous$$ake the body move
         moveDirection(direction);    
         //Change direction based on fudged turnPoint
         float dist = Vector3.Distance(transform.position, playerControl.turnPoint);
         if(dist < $$anonymous$$ARGIN)
         {
             direction = playerControl.direction;
         }
         
     }
     
     public void moveDirection(int direction)
     {
         switch(direction)
         {
         case 1:
             transform.Translate (Vector3.forward * Time.deltaTime * playerControl.speed);
             break;
         case 2:
             transform.Translate (-Vector3.forward * Time.deltaTime * playerControl.speed);
             break;
         case 3:
             transform.Translate (Vector3.left * Time.deltaTime * playerControl.speed);
             break;
         case 4:
             transform.Translate (Vector3.right * Time.deltaTime * playerControl.speed);
             break;
         }
     }
     
 }



That's my code for the Sphere to follow the player controlled sphere.

avatar image robertbu · May 09, 2013 at 03:58 PM 1
Share

Without seeing your playerControl script, I'm guessing a bit. But let me start with a hack:

    if(dist < $$anonymous$$ARGIN) {
      transform.position = playerControl.turnPoint;  // HAC$$anonymous$$
      direction = playerControl.direction;
    }

This corrects the error at each turn point so that they do not compound. Now a bit of a rewrite to use Vector3.$$anonymous$$oveTowards():

 public class BodyController : $$anonymous$$onoBehaviour {
     private Vector3 v3NextPos;
     PlayerControl playerControl;
  
     void Start() {
        playerControl = GameObject.FindWithTag("Player").GetComponent<PlayerControl>();
        v3NextPos = playerControl.turnPoint;
     }
  
     void Update() {
        //$$anonymous$$ake the body move
        transform.position = Vector3.$$anonymous$$oveTowards(transform.position, v3NextPos,Time.deltaTime * playerControl.speed); 
  
        if(transform.position == v3NextPos) {
          v3NextPos = playerControl.turnPoint;
        }
     }
 }

Note you will likely have to adjust playerControl.speed.

avatar image MrZalib · May 09, 2013 at 04:01 PM 1
Share

You sir, I would hug you if could. Thank you for helping me with a problem that has plagued me for a long time.

Show more comments

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

14 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

Related Questions

Different between transform.Translate() and Vector3.MoveTowards? 1 Answer

Object keeps moving up even when StopCoroutine is called 2 Answers

Applying Forces, independent of Frame Rate? 1 Answer

Low Frame Rate after Deserialization 0 Answers

Can someone please help with C#? 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