Why is my moving platform getting stuck?
I'm trying to do a moving platform between an array of transforms and its positions. Here's the code (sorry if it's really obvious, but it's my first time trying a engine).
public float speed = 1;
public Transform[] positions;
private string direction = "Towards";
private int counter = 0;
void Start()
{
if (positions.Length > 0 || positions == null)
transform.position = positions[0].position;
}
void Update()
{
if (positions.Length < 2 || positions == null)
return;
if (counter < positions.Length - 1 && direction.Equals("Towards"))
counter++;
else if (counter > 0 && direction.Equals("Backwards"))
counter--;
if (counter == positions.Length - 1)
direction = "Backwards";
else if (counter == 0)
direction = "Towards";
transform.position = Vector3.MoveTowards(transform.position, positions[counter].position, speed * Time.deltaTime);
}
I posted my answer. Beside the complexity that is making it difficult to follow the logic of the code, it is missing a critical test: it needs to wait until the animation has reached it's destination before switching directions. that what the magnitude of position a - position b does.
We get the distance between them and then test against some threshold, because positions are unlikely to be exactly equal, ever. The reasons are due to the facts of the animation process, and that positions have floating point components that almost never become exactly equal.
Answer by streeetwalker · Mar 16, 2020 at 09:12 PM
@ricarditomontserrat, I don't know, but it is too complicated. Simplify it!
The following assumes position 0 moves to the left, and position 1 moves to the right, and transform.position is already on the right at the start of this code.
So well start out moving left first. If you want to start on the left and move to the right first, then set counter = 1 at the start:
int counter = 0;
void update() {
if (positions.Length < 2 || positions == null) {
if( ( transform.position - positions[counter].position ).magnitude < 0.001 ){ // we reached the destination!
counter = (counter + 1) % 2 // alternate between 0 and 1
}
transform.position = Vector3.MoveTowards(transform.position, positions[counter].position, speed * Time.deltaTime);
}
}
a note about my personal preference: I find code easier to follow if you let blocks of code return naturally without placing returns in the middle.
Thank you so much! It's kind of funny because I tried to make it readable but it became worst lol.
@ricarditomontserrat, Hey , I just created a problem by changing your logic to exit the if block naturally and line of code had a problem already:
if (positions.Length < 2 || positions == null) {
That will throw an error if positions is null because it is checking for the length first. The way compound conditions work is: the first clause of the condition evaluated first and the program decides if it needs to evaluate the next clause from left to right. So if your object is null, trying to get the length first will cause an error.
Therefore, always check for null first in any compound condition.
To fix that, and the problem I caused, you should change this to:
if( positions != null && (positions.length > 1 && positions.length < 2)
That way, if the first one is not true - it is null, then it will not try evaluate the next clause and it will skip the if block.
Sorry and hope it helps!
Yeah, I noticed that and changed it at first sight, but thanks anyway :D