MoveTowards, Speed Increasing?

Hi there,
I have a script that moves my player to a position on doubleTap. I move him like this…

	IEnumerator performMove(){
		print("performMove");
		while(brainMove){	
			brainTransform.position = Vector2.MoveTowards(brainTransform.position, wrldInputPos, brainSpeed * Time.deltaTime);
			yield return null;
		}
	}

The trouble is, with each double tap, the speed of the movement seems to increase. Any ideas?

I guess you call performMove every time you touch?

It is a double tap that allows for this to happen.

	/////1
	////HANDLE DOUBLE TAP
	/////////////////////
	void recordTap(){
		tapCount++;
		print("perfromTask()  tapCount = " + tapCount);
		//SAFETY VALVE - so no over tap
		if(tapCount > 2){
			print("tapCount > 2, reset to 0");
			tapCount = 0;	
			return;
		}
		else if(tapCount == 1){
			time1 = Time.time;
			print("time1 " + time1);
			StartCoroutine(setValve());///timer yield to reset tapCount with in timeSpan
			return;
		}
		else if(tapCount == 2){
			time2 = Time.time; 
			print("doubleTap!!!");
			wrldInputPos = cam.ScreenToWorldPoint(inputPos);
			brainMove = false;
			StartCoroutine(performMove());
		}			
	}
	///resets tapCount if time x passes (doubleTap)
	IEnumerator setValve(){
		print("setValve()  time " + Time.time);
		yield return new WaitForSeconds(0.2f);
		print("setValve 2 time = " + Time.time);
		tapCount = 0;
		print("tapCount reset!!!!  time = " + Time.time);
	}	
	///perform move
	IEnumerator performMove(){
		print("performMove");
		brainMove = true;
		while(brainMove){	
			brainTransform.position = Vector2.MoveTowards(brainTransform.position, wrldInputPos, brainSpeed * Time.deltaTime);
			yield return null;
		}
	}

Hi. Looks like you are accumulating multiple coroutines executions. Your while loop may never complete. Even if it seems like your object stopped but it is deceptive since it just reached destination. But loop goes on. Even next time you set brainMove = false it will be right away set to true by another coroutine execution and both loops continue. The more double taps - the more indefinite loops. You need either stop a previous coroutine (performance problem here since you would have to invoke it by name) or add another condition for loop termination like:

if (brainTransform.position == wrldInputPos)
break;
1 Like

In addition, it means that you can change your code like this:

while(brainTransform.position != wrldInputPos){   
brainTransform.position = Vector2.MoveTowards(brainTransform.position, wrldInputPos, brainSpeed * Time.deltaTime);
yield return null;
}
brainMove = false;

And you can use brainMove variable to stop a second doubletap if the first one is still executing. Which is a second condition. You can do that by checking brainMove == true before calling the coroutine.

Thanks.
:stuck_out_tongue:

I updated the code to this…

		while(brainTransform.position != wrldInputPos){   
		brainTransform.position = Vector2.MoveTowards(brainTransform.position, wrldInputPos, brainSpeed * Time.deltaTime);
		yield return null;
		}

The same speed increase issues are happening.
Any ideas? I dont full get why this increase is occurring.

Always taking the actual position of the brainTransform means the distance gets smaller and smaller. You need to preserve the start position und use that one for the interpolation towards the goal.

Vector2 startPosition = brainTransform.position;
while(brainTransform.position != wrldInputPos){  
    brainTransform.position = Vector2.MoveTowards(startPosition, wrldInputPos, brainSpeed * Time.deltaTime);
    yield return null;
}

Ah, I see, thanks.

On a related note, this type of movement is very static, very linear, there is no “bounce” to it. A constant speed while moving, is not very “sexy”. Is there any tips anyone might have to create an easing effect? Another method? I am doing my best to stay away from Tweens.

I just added in the code suggested, by Dantus, but now, the transform, does not really move at all. Instead, he does move, but very minutely, and jerks back to start pos. He does this infinitely.

Though you are using Lerp. Code is untested.

Vector2 startPosition = brainTransform.position;
float lerpFactor = 0.0f;
while(lerpFactor <= 1.0f){
    lerpFactor = lerpFactor + brainSpeed * Time.deltaTime;
    brainTransform.position = Vector2.MoveTowards(startPosition, wrldInputPos, lerpFactor);
    yield return null;
}
brainTransform.position = wrldInputPos;

Thanks. Will not be able to test for a bit but, does lerp create any type of easing effect? Like ease in, ease out?

Sorry. The termination condition was not right. Try this:

while(true)
{  
float dist1 = brainSpeed * Time.deltaTime;
float dist2 = (wrldInputPos - brainTransform.position).magnitude;
if (dist1 > dist2)
{
brainTransform.position = wrldInputPos;
break;
}
brainTransform.position = Vector2.MoveTowards(brainTransform.position, wrldInputPos, dist1);
yield return null;
}

Awesome. Thank you.