Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Need help with waypoint movement.

Discussion in 'Scripting' started by edvis1433, Aug 20, 2018.

  1. edvis1433

    edvis1433

    Joined:
    Apr 11, 2018
    Posts:
    19
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GhostMove : MonoBehaviour {
    6.     public Transform[] waypoints;
    7.     int cur = 0;
    8.  
    9.     public float speed = 0.3f;
    10.  
    11.     void FixedUpdate () {
    12.         if (transform.position != waypoints [cur].position) {
    13.             Vector2 p = Vector2.MoveTowards (transform.position, waypoints[cur].position, speed);
    14.             GetComponent<Rigidbody2D>().MovePosition(p);
    15.         }
    16.         else cur = (cur + 1) % waypoints.Length;
    17.  
    18.         Vector2 dir = waypoints [cur].position - transform.position;
    19.         GetComponent<Animator> ().SetFloat ("DirX", dir.x);
    20.         GetComponent<Animator> ().SetFloat ("DirY", dir.y);
    21.     }
    22.     void OnTriggerEnter2D(Collider2D co) {
    23.         if (co.name == "pacman")
    24.             Destroy(co.gameObject);
    25.     }
    26. }
    27.  

    So i have a problem where the ghost in pacman moves to the first waypoint and doesnt continue, and not sure where is the problem in my code.
     

    Attached Files:

  2. Mordus

    Mordus

    Joined:
    Jun 18, 2015
    Posts:
    174
    Code (CSharp):
    1. transform.position != waypoints [cur].position
    Have you checked if this ever actually equates to false and executes line 16?
    Directly comparing floating point numbers with == is generally not a good idea due to precision issues.
    2 floats can be different by miniscule amounts when they 'should' be the same i.e: 0.4999999 instead of 0.5.
     
  3. edvis1433

    edvis1433

    Joined:
    Apr 11, 2018
    Posts:
    19
    well i mean everything is full numbers (the waypoints and the ghost himself) none of them have like 0.5 of their positions. Sorry if i didnt understand your message clearly what you are trying to say, correct me if im completely wrong
     
  4. barskey

    barskey

    Joined:
    Nov 19, 2017
    Posts:
    207
    It's most helpful to add Debug statements or Breakpoints to help determine what is going on during runtime. It might be where you are comparing transform.position to waypoints [cur].position. If they are not exactly equal, you are setting your next move position and moving. Else you are updating your waypoints index. But the problem might be that the "else" is never being implemented, because
    transform.position != waypoints [cur].position
    probably always evaluates to true. You will need to use an "almost equal to" type of comparison to find out if it has reached the destination.

    Also, it would probably be better to get in the habit of always including your curly braces for if statements. It is more readable, and more consistent.
     
  5. edvis1433

    edvis1433

    Joined:
    Apr 11, 2018
    Posts:
    19
    So how am i supposed to do it? Im new to this and its even hard sometimes to understand to people who try to help, and im not sure how to do it.
     
  6. barskey

    barskey

    Joined:
    Nov 19, 2017
    Posts:
    207
    Well, when you do a comparison of position, you want to keep in mind that the values of the Vector3 of the position are floats, and they are almost never going to be equal. So one method is to calculate the distance between the transform.position and the goal position (which will be a float), and check that it is "close enough". For example:
    Code (CSharp):
    1. float distCheck = 0.02f;
    2.  
    3. void FixedUpdate ()
    4. {
    5.   float distToWaypoint = Vector3.Distance (waypoints [cur].position, transform.position);
    6.   if (distToWaypoint <= distCheck)
    7.   {
    8.     // have reached waypoint - do stuff here
    9.   }
    10.   else
    11.   {
    12.     // not yet at waypoint. Keep going
    13.   }
    14. }
    Note that if you use the == operator on a Vector3, it will still return true if they are approximately equal (< 1e-5). But since you are checking distances in every fixed update frame, it might overshoot from one fixedupdate to the next, hence we relax the distance check a little bit, as above.
    https://docs.unity3d.com/ScriptReference/Vector3-operator_eq.html
     
    europeanrich likes this.
  7. Mordus

    Mordus

    Joined:
    Jun 18, 2015
    Posts:
    174
    Code (CSharp):
    1. transform.position != waypoints [cur].position
    What's happening here is you're comparing 2 vector3's to see if they are the same (well, you're checking to see if they're NOT the same). They will only ever == each other if their x, y, and z are all exactly the same, right down to the smallest decimal point.

    Vector3.x, y and z are of the type float. floating point numbers have issues with precision, this is a topic in itself but just take my word for it when i say that when working with floating point numbers they can vary by tiny amounts even when it feels like they shouldn't and comparing them with == or != is not reliable.

    The way to compare floating point numbers is not to use == or != but to check if the difference between them is above/below a certain amount. I was going to post an example but barskey just posted pretty much what i was going to do, so i'll leave it at that.

    Doesn't matter, you can still end up with a floating point number that says 4.999999 instead of 5 and won't be == to another floating point number that says 5 or 5.000001 or something. If you've ever played around moving and rotating objects in the editor you may occasionally see this happening to the position shown in the editor.

    Also, you are dealing with decimal points. You may have aligned your waypoints to some whole numbers, but your ghost is not. You've moving it by 0.3 each update.
     
    europeanrich likes this.
  8. edvis1433

    edvis1433

    Joined:
    Apr 11, 2018
    Posts:
    19
    Okay i get it what you want to say but i still cant figure out how to do it. Because when i try to change something the the ghost just keeps going down out of the map, so im lost on how to do it.
     
  9. barskey

    barskey

    Joined:
    Nov 19, 2017
    Posts:
    207
    I am not following your waypoint index logic. Assuming waypoints is an array of gamebojects, then to summarize your update loop above:
    Code (CSharp):
    1. // cur (waypoint index) starts at zero
    2. // if ghost position is not equal to current waypoint position then
    3. // move toward the current waypoint position
    4. // else set cur to the remainder of cur + 1 divided by the number of waypoints
    5. // set animator floats
    6.  
    Say you have 5 waypoints. When it reaches the first waypoint (the else in the if statement above), cur gets set to (0 + 1) % 5, which is 4. If it ever reached 4, cur would get set to (4 + 1) % 5, which is 0. So I think you have some issues with your logic in incrementing the waypoint index.

    Maybe you want to do something like:
    cur++;
    if (cur >= waypoints.Length)
    {
    // do something herre when you reached your last waypoint
    }