When talking about 'speed' there are a couple of ways of thinking about it. You can think about it one way, like 'meters per frame' (ie: for each frame, I want the player to move X meters). For that type of functionality, see this:
public IEnumerator MoveAtSpeedCoroutine(Vector3 end, float speed){
//while you are far enough away to move
while (Vector3.Distance(this.transform.position,end)>speed){
//MoveTowards the end position by a given distance
this.transform.position = Vector3.MoveTowards(this.transform.position, end, speed);
//wait for a frame and repeat
yield return 0;
}
//Since you are really really close, now you can just go to the final position.
this.transform.position = end;
}
The problem with this way is it can look weird if the framerate is not perfectly constant.
The other way (and the best way) would be to keep track of 'meters per second'. This way, if the game lags out for a couple of frames, it should still look just fine (ie: if you want to move X meters over 1 second, and if you get a constant 100 frames per second, each frame the object will be moved X/100th of a meter; Whereas, lets say I get to a really choppy part of my game (heaven forbid) that the game was lagging for the whole second, and only ran one frame in one second, then the object would be moved X/1). In the first way, if I ran the same game on two computers, and the first computer was laggy and the second one wasn't, and I played my game (lets say a racing game), then the laggy computer would always lose and it will always move slower than the non-laggy computer. Whereas with the second way (code below), even if one computer laggs a bunch, they both should keep neck and neck (even though on the non-laggy computer will look a bunch better :D) The code for the second way is as follows:
public IEnumerator MoveAtSpeedCoroutine(Vector3 end, float speed){
while (Vector3.Distance(this.transform.position,end)>speed*Time.deltaTime){
this.transform.position = Vector3.MoveTowards(this.transform.position, end, speed*Time.deltaTime);
yield return 0;
}
this.transform.position = end;
}
Note, the only change is multiplying speed by Time.deltaTime - this converts it from 'meters per frame' to 'meters per second'. Why this works is Time.deltaTime is the amount of time that passed last frame (a percent out of 1 second). If the computer lagged out for a whole second, Time.deltaTime would be 1, and if your game rendered at 200 FPS (5ms total render time) for this frame, then Time.deltaTime would be 0.005. If you multiply your speed by this number, then no matter your framerate is, that speed is the amount of meters the object will move in 1 second.
With that said, you could do this with lerp as well (I don't care for it in this instance myself... but this is an option). You can do it like so:
public IEnumerator MoveAtSpeedCoroutine(Vector3 end, float speed){
Vector3 start = this.transform.position;
//total time this has been running
float runningTime = 0;
//the longest it would take to get to the destination at this speed
float totalRunningTime = Vector3.Distance(start,end) / speed;
//for the length of time it takes to get to the end position
while (runningTime<totalRunningTime){
//keep track of the time each frame
runningTime += Time.deltaTime;
//lerp between start and end, based on the current amount of time that has passed
// and the total amount of time it would take to get there at this speed.
this.transform.position = Vector3.Lerp(start, end, runningTime/totalRunningTime);
yield return 0;
}
this.transform.position = end;
}
And even more still, one way to look at speed is using physics. So... you got a lot of choices :D
Hope that helps and good luck! :D
ps. Scale...
I would do that as follows:
public IEnumerator MoveAtSpeedCoroutine(Vector3 end, float speed){
//figure out the scale you want to use - here I will just take the average scale
float scale = (this.transform.localScale.x+this.transform.localScale.y+this.transform.localScale.z)/3;
//lets now use the scale to make a new speed. The new speed will be based off of the old speed
//and also the scale.
float speedAtScale = scale * speed;
while (Vector3.Distance(this.transform.position,end)>speedAtScale*Time.deltaTime){
this.transform.position = Vector3.MoveTowards(this.transform.position, end, speedAtScale*Time.deltaTime);
yield return 0;
}
this.transform.position = end;
}