- Home /
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?
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;
}
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?
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.
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.
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.
You sir, I would hug you if could. Thank you for helping me with a problem that has plagued me for a long time.
Your answer
Follow this Question
Related Questions
how to apply translate to gameobject? 1 Answer
[SOLVED] Camera jitters while moving towards/away from player 2 Answers
Translate not working properly 1 Answer
Why are my controls laggy 1 Answer