I have a simple script that makes an object go up and down repeatedly. However, the object keeps either gradually sinking or gradually rising. Eventually, the object will be nowhere near where it originally was. This is the script:
#pragma strict
var speed = 2.0;
var duration = 1.0;
private var rising = 0;
var spawn : GameObject;
spawn = new GameObject();
spawn.transform.position = transform.position;
InvokeRepeating("Change", duration, duration);
function Update () {
if(rising > 1){
rising = 0;
}
if(rising == 0){
transform.Translate(Vector3.up * speed * Time.deltaTime);
}
else{
transform.Translate(Vector3.down * speed * Time.deltaTime);
}
}
function Change () {
rising ++;
if(rising == 0){
transform.position.y = 0;
PrefabUtility.RevertPrefabInstance(gameObject);
}
}
I added in the variable of “spawn” to try and prevent this from happening, but it didn’t do anything. I also tried reverting the object to its prefab every time it lowered, but that didn’t do anything either. Does anybody know what’s wrong with the script?
You haven’t currently got your call to InvokeRepeating inside a function (as @767_2 commented), so Change() is never getting called. That’s why your object keeps rising or falling.
Although, TBH, if all you’re trying to do is get a repeating rising/falling loop, you could achieve it much easier using Mathf.PingPong. Then your entire code could be replaced with:
var speed = 2.0;
var duration = 1.0;
function Update () {
transform.position = Vector3(transform.position.x, Mathf.PingPong(Time.time, duration) * speed, transform.position.z);
}
You’re getting cumulative error. That is, the way you’ve set this up, if there’s any previous error from the last cycle, then the next cycle just adds to it. Then the next cycle adds more error to that, and so on.
So where does this error come from? Well, you’re moving at a constant speed on every frame, but the amount of that movement doesn’t have any hard limit. You just switch directions every now and then. So, you’ll never be exactly however-many meters you imagine from the origin when you switch – you’ll be a little more or less than that. Thus, error, added to the previous errors. Your object’s average position does a random walk.
To fix this, I would recommend a completely different approach. Instead of defining a speed and duration, define the speed plus upper and lower limits of where the object should go. So, the code would look something like this:
public float minY = 0f;
public float maxY = 2f;
float dir = 1f;
void Update() {
transform.Translate(new Vector3(0, dir, 0));
if ((dir > 0 && transform.position.y > maxY)
|| (dir < 0 && transform.position.y < minY)) {
dir = -dir;
}
}
No need for InvokeRepeating, and no drift!