Reputation: 4806
I am attempting to translate a chess piece up, across and then back down using the lerp
functionality of unity. However, whenever I trigger this script, the entire session freezes.
Using the unity debugger, I have narrowed the problem down to this section of code.
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
because it would appear that none of the variables are altering and consequently, the entire loop is infinite.
Here is the entire section of code dedicated to handling the movement (the vector values are currently arbitrary).
public class MovePiece : MonoBehaviour {
Vector3 startPoint;
Vector3 endPoint;
float speed = 10;
float startTime;
private bool moving = false;
private bool up = false;
private bool across = false;
private bool down = false;
public void Start()
{
startPoint = gameObject.GetComponent<Transform>().position;
startTime = Time.time;
moving = true;
Debug.Log("Moving Piece");
}
void Update() {
if (!moving)
{
Destroy(this);
return;
}
moveManager();
}
void moveManager()
{
if (!up)
{
lerpUp();
return;
}
if (!across)
{
lerpAcross();
return;
}
if (!down)
{
lerpDown();
return;
}
}
private void lerpUp()
{
Debug.Log("Upwards");
startPoint = gameObject.GetComponent<Transform>().position;
endPoint = startPoint + new Vector3(0, 0, 50);
float journeyLength = Vector3.Distance(startPoint, endPoint);
float fracJourney;
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
up = true;
Debug.Log("Upwards Finished");
return;
}
private void lerpAcross()
{
Debug.Log("Across");
startPoint = gameObject.GetComponent<Transform>().position;
endPoint = startPoint + new Vector3(0, 50, 0);
float journeyLength = Vector3.Distance(startPoint, endPoint);
float fracJourney;
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
across = true;
Debug.Log("Across Finished");
return;
}
private void lerpDown()
{
Debug.Log("Down");
startPoint = gameObject.GetComponent<Transform>().position;
endPoint = startPoint + new Vector3(0, 0, -50);
float journeyLength = Vector3.Distance(startPoint, endPoint);
float fracJourney;
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
down = true;
Debug.Log("Down Finished");
moving = false;
Debug.Log("Moving Finished");
return;
}
}
}
I have been trying for days to narrow this problem down, to no avail, so any help would be greatly appreciated.
Upvotes: 2
Views: 5084
Reputation: 15941
You've got more than one problem here.
The first is that you're using a loop inside your lerp functions. The game won't update the render output until the loop finishes. It doesn't matter if the loop is infinite or not, it's not going to execute only one iteration, it's going to do all of them (it also doesn't help that Time.time
doesn't change during this process).
Second is that you're calculating the distance moved as an amount of distance from the start of the application not the start of the current move.
Third, you're calling Vector3.lerp() passing it a third parameter (the "float-percentage") with the value of speed
not the fractional amount that should be calculated. e.g. Vector3.Lerp(startPoint, endPoint, 0.5f);
will return the midpoint between startPoint
and endPoint
.
Fourth, there's no reason to have four methods for lerping your animation. You only need one, but you have to pass it the desired destination as well (rather than having four methods that imply different destinations).
Fifth, you're calculating journeyLength
as the distance between the startPoint
and the endPoint
despite having previously calculated the endPoint
as startPoint + distance
(that's what new Vector3(0,0,50)
is: a distance!)
Upvotes: 1
Reputation: 8163
do
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
} while (fracJourney <= 1);
Update()
only runs once per frame, and Time
only gets updated when it does, so Time
will never change in the matter of one Update()
, so (Time.time - startTime) * speed
will always stay the same, so distCovered
will never change, so fracJourney
will never change, so fracJourney <= 1
will never change, so you are stuck in the loop forever.
If you are looking for a fix, you shouldnt need a while
loop inside of an Update()
function, almost ever. Use the Update()
function itself as your loop, or use an IEnumerator
where you can yield out and let a frame pass, as such:
public IEnumerator MyLoop()
{
while (fracJourney <= 1)
{
float distCovered = (Time.time - startTime) * speed;
fracJourney = distCovered / journeyLength;
Debug.Log(fracJourney);
transform.position = Vector3.Lerp(startPoint, endPoint, speed);
yield return null; //< --- yield out and let a frame pass
}
}
Upvotes: 1