Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

move GameObject through array of position vectors (using waypoints?)

Discussion in 'Scripting' started by markhirsch, Sep 19, 2018.

  1. markhirsch

    markhirsch

    Joined:
    Sep 19, 2018
    Posts:
    2
    I have a CSV file of position vectors that I have successfully imported and parsed into a script. I need to move an object through each vector position in the array and am wondering what the best practice is for executing this in Unity. Currently, I have been working with creating 'waypoints' but this will only work if I can set the position of the waypoint at the beginning of the script...which I haven't been able to figure out. It seems most waypoint tutorials require one to drag a GameObject into the waypoint/element slot in the Unity GUI. (such as in this tutorial
    )

    Here is the code as it stands--with a function for importing the vectors and the a method for setting up waypoints (in the Update() function):
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Waypoints : MonoBehaviour
    6. {
    7.  
    8.     public GameObject[] waypoints;
    9.  
    10.     public Vector3[] vectors; // array to hold vectors from CSV file
    11.  
    12.  
    13.     public TextAsset csvFile; // to parse CSV to text
    14.  
    15.     // parameters from waypoint tutorial
    16.     int current = 0;
    17.     float rotSpeed;
    18.     public float speed = 8;
    19.     float WPradius = 1;
    20.  
    21.     void Start()
    22.     {
    23.         loadVectors();
    24.     }
    25.  
    26.     void Update()
    27.     {
    28.         if (Vector3.Distance(waypoints[current].transform.position, transform.position) < WPradius)
    29.         {
    30.             current++;
    31.             if (current >= waypoints.Length)
    32.             {
    33.                 current = 0;
    34.             }
    35.         }
    36.         transform.position = Vector3.MoveTowards(transform.position, waypoints[current].transform.position, Time.deltaTime * speed);
    37.  
    38.     }
    39.  
    40.     void loadVectors(){
    41.         string[] data = csvFile.text.Split('\n');
    42.         for (int i = 0; i < data.Length; i++)      
    43.         {
    44.             string[] fields = data[i].Split(' ');
    45.             vectors[i] = new Vector3(float.Parse(fields[1]), float.Parse(fields[2]), float.Parse(fields[3]));
    46.         }
    47.     }
    48. }
    Here are the contents of the csv file I'm using to test this with:
    Code (CSharp):
    1. 0 -5.0 0.0 0.0
    2. 1 -4.0 0.0 0.0
    3. 2 -3.0 0.0 0.0
    4. 3 -2.0 0.0 0.0
    5. 4 -1.0 0.0 0.0
    6. 5 0.0 0.0 0.0
    7. 6 1.0 0.0 0.0
    8. 7 2.0 0.0 0.0
    9. 8 3.0 0.0 0.0
    10. 9 4.0 0.0 0.0
    11. 10 5.0 0.0 0.0
    12. 11 6.0 0.0 0.0
     
    webfan likes this.
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    I'm not really sure what your question is. You seem to have everything sorted.

    If you don't want the object to begin moving immediately, you could move everything out of Update() and into a coroutine which triggers at the end of LoadVectors(), which you could call at any point in the program's execution.
     
  3. markhirsch

    markhirsch

    Joined:
    Sep 19, 2018
    Posts:
    2
    hey GroZZleR, thanks for the reply. My question is how to assign the vectors to the waypoints at the beginning of the script. Currently, I need to (in the GUI) create GameObjects and then drag them into however many 'waypoints' I create. I would like to be able to do this at the beginning of the script because in the actual application I will have thousands of vectors to move to.
    Before I started looking at this 'waypoint' method, I initially thought this would be as simple as setting the 'transform.position' of the GameObject equal to each new vector but when I do this the object doesn't seem to move at all. Something like this for example (run in the Update() function):
    Code (CSharp):
    1.         string[] data = csvFile.text.Split('\n');
    2.         for (int i = 0; i < records.Length; i++)
    3.         {
    4.             string[] fields = data[i].Split(' ');
    5.             //cubeTest.transform.Rotate(float.Parse(fields[1]), float.Parse(fields[2]), float.Parse(fields[3]));
    6.             newPos = new Vector3(float.Parse(fields[1]), float.Parse(fields[2]), float.Parse(fields[3]));
    7.             print(newPos);
    8.             cubeTest.transform.position = newPos;
    9.         }
    Strangely, the rotate (commented out) works just fine. But the position does not seem to change
     
  4. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Why use GameObject for waypoints? Just for visualization purposes to see where your waypoints are in the scene? If so, just use DrawGizmos for debugging purposes.

    If you must use game objects, then you can just create a new GameObject in script for each vector loaded from the CSV. You don't have to mess with dragging in game objects in the inspector.

    The way your code looks right now, you're setting the cube position to every vector the loop runs through. When the loop finishes, the cube is set to whatever the last vector is.

    transform.Rotate is additive. Setting the position is not. That's why they behave differently.
     
    Last edited: Sep 19, 2018
  5. neoshaman

    neoshaman

    Joined:
    Feb 11, 2011
    Posts:
    6,466
    To recap:
    1 - you have a waypoint list file
    2 - you parse it into an array
    3 - you want to assign it to whatever game object you want
    4 - you want it to follow the waypoint system at runtime after being initialized?

    It seems that 1 and 2 has been figured out, so you either need to 3 or 4.
    Well the array is stored somewhere, just pass it to the gameobject you created, you don't have to use monobehavior so just create a class that handle finding and passing teh csv data. you need a custom database, assigning stuff into unity is basically building a database for your project. What I would do, is:
    - create a gameobject, initialize the object on awake
    - has it request a waypoint to the waypoint handler on start using an ID (depending on the complexity of the project, it's hardcoded because there is only one waypoint possible, or the scene manager know which object are affected by which waypoint and handle initialization)
    - the waypoint database handler look at the id
    - if no object had request it
    -- load the proper waypoint, and put the object onto teh waypoint list, pass the reference to the waypoint array
    -- else put the object on the waypoint list, pass the reference to the object
    - when the object is destroyed, he remove itself from the waypoint list
    - if the waypoint list of object is zero, destroy the waypoint data
     
  6. ano99

    ano99

    Joined:
    Jul 16, 2019
    Posts:
    3
    hi !
    I read csv file to transform animation in x y z .
    And my code Like this :
    -----------------------------------------------------------------------------------------------------------
    public TextAsset coordinates;
    public float moveSpeed;
    // public float MoveSpeed =
    string[] coordinatesArray;
    int currentPointIndex = 1;
    Vector3 destinationVector;
    Quaternion lol;

    void Start()
    {
    coordinatesArray = coordinates.text.Split(new char[] { '\n' });
    }
    void Update()
    {

    if (destinationVector == null || transform.position == destinationVector)
    {
    currentPointIndex = currentPointIndex < coordinatesArray.Length - 1 ? currentPointIndex + 1: 1;
    if (!string.IsNullOrWhiteSpace(coordinatesArray[currentPointIndex]))
    {

    string[] xyz = coordinatesArray[currentPointIndex].Split(new char[] { ',' });
    destinationVector = new Vector3(float.Parse(xyz[0]), float.Parse(xyz[2]) * -1, float.Parse(xyz[1]));
    transform.rotation = Quaternion.Euler(float.Parse(xyz[3]), float.Parse(xyz[5]), float.Parse(xyz[4]));
    /* float terrainWhereWeAre = Terrain.activeTerrain.SampleHeight(transform.position);
    if(terrainWhereWeAre >-123.0f)
    {
    transform.position = new Vector3(transform.position.x, terrainWhereWeAre, transform.position.z);
    }*/
    }
    }
    else
    {
    transform.position = Vector3.MoveTowards(transform.localPosition, destinationVector, Time.deltaTime * moveSpeed);
    }
    }


    -----------------------------------------------------------------------------------------------------
    so I want to skip 10 line in csv and i don't know how can I do it ?
    and plz help me >> <<
     
  7. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,900
  8. ano99

    ano99

    Joined:
    Jul 16, 2019
    Posts:
    3
    Code (CSharp):
    1.  
    2. public TextAsset coordinates;
    3. public float moveSpeed;
    4. string[] coordinatesArray;
    5. int currentPointIndex = 1;
    6. Vector3 destinationVector;
    7. Quaternion lol;
    8.  
    9. void Start()
    10. {
    11. coordinatesArray = coordinates.text.Split(new char[] { '\n' });
    12. }
    13. void Update()
    14. {
    15.  
    16. if (destinationVector == null || transform.position == destinationVector)
    17. {
    18. currentPointIndex = currentPointIndex < coordinatesArray.Length - 1 ? currentPointIndex + 1: 1;
    19. if (!string.IsNullOrWhiteSpace(coordinatesArray[currentPointIndex]))
    20. {
    21.  
    22. string[] xyz = coordinatesArray[currentPointIndex].Split(new char[] { ',' });
    23. destinationVector = new Vector3(float.Parse(xyz[0]), float.Parse(xyz[2]) * -1, float.Parse(xyz[1]));
    24. transform.rotation = Quaternion.Euler(float.Parse(xyz[3]), float.Parse(xyz[5]), float.Parse(xyz[4]));
    25. /* float terrainWhereWeAre = Terrain.activeTerrain.SampleHeight(transform.position);
    26. if(terrainWhereWeAre >-123.0f)
    27. {
    28. transform.position = new Vector3(transform.position.x, terrainWhereWeAre, transform.position.z);
    29. }*/
    30. }
    31. }
    32. else
    33. {
    34. transform.position = Vector3.MoveTowards(transform.localPosition, destinationVector, Time.deltaTime * moveSpeed);
    35. }
    36. }
    And i am read data using public TextAsset coordinates ..
    so I want read from csv file skip 10 line in csv
     
  9. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,900
    if you want to skip the first 10 lines, just set the currentPointIndex to 10 at the beginning, if you want to skip 10 lines *somewhere* then just increase it by 10 *somewhere* (if this later, you need to put this in or after the line 18