Search Unity

Choosing Array from array

Discussion in 'Scripting' started by jackvob1, Jul 1, 2020.

  1. jackvob1

    jackvob1

    Joined:
    Mar 2, 2018
    Posts:
    38
    Right now i have a car with only 1 waypoint so i want to change it when in play mode but i dont know how to choose Array from array, my script right now :


    [Header("AI")]
    public GameObject NPC;
    public NavMeshAgent AgentA;

    [Header("Waypoint Settings")]
    int CurrentWP = 0;
    public float accuracy = 5f;

    [Header("Waypoints1")]
    public GameObject[] waypoints1;

    [Header("Waypoints2")]
    public GameObject[] waypoints2;

    void Update()
    {

    if (waypoints1.Length == 0) return;

    if (Vector3.Distance(waypoints1[CurrentWP].transform.position, NPC.transform.position) < accuracy)
    {
    CurrentWP++;
    }

    AgentA.SetDestination(waypoints1[CurrentWP].transform.position);
    }

    Any Tips how do i do it ?
     
  2. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Please use code tags when posting code examples, to add syntax highlighting and so on.

    I'm not quite sure i understand what you are asking. From how you formulated the question "choosing an array from arrays", i would assume you are talking about data structures like Type[,], Type[][] or List<List<Type>>, literally having "arrays of arrays" and wanting to get one of the internal arrays back. You also do have two separate arrays waypoints1 and waypoints2, so if your question is how to avoid having "waypoints3, waypoints4, ..." then the easiest answer would be to use Lists instead of arrays (for the dynamic size), and having one List<List<GameObject>> to which you can add List<GameObject> entries, like so:
    Code (CSharp):
    1. // We create a list of lists of the desired type
    2. List<List<GameObject>> waypoints; // instantiate in Start() to new List<List<GameObject>>();
    3.  
    4. // Given some existing lists of data, like your arrays now..
    5. List<GameObject> waypoints1 = ...
    6. List<GameObject> waypoints2 = ...
    7.  
    8. // We can simply add them to the list of lists like so:
    9. waypoints.Add(waypoints1);
    10. waypoints.Add(waypoints2);
    Using a list of lists, you can still iterate it using a for-loop and basically do everything else like you are used to from arrays. Here waypoints[0] would represent your waypoints1 list, and waypoints[1] would represent your waypoints2 list. You can then either get those from the list of lists and save them in a new list to work with, or directly use a nested for loop to iterate all segments, since you can access elements in the arrays below directly from the list of lists as well. Using waypoints[0][0], we would get the first element from waypoints1 and so on.

    However, if this is what you are asking about i'm not sure if it's the right approach. Why do you need two different arrays of waypoints in the first place? Should the npcs alternate between the waypoints from the first and second list? Most of the times, when you have a waypoint system, you want it to be one large list / array of points the npc follows, not several lists. In my mind a grid-like structure does not seem to make a whole lot of sense for a waypoint system, but of course there way be very much viable situations i'm missing where that's the case.
     
  3. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    I don't understand your question. I see you have two arrays, but not an array of arrays. Are you wanting to choose between the two sets of waypoints? What is your condition for using waypoints2 vs waypoints1?
     
  4. jackvob1

    jackvob1

    Joined:
    Mar 2, 2018
    Posts:
    38
    Let just say i want to create a scenario in the highway with 2 lanes where there i'm driving a car with a lot of ai,
    and the ai i want it to look like a person who is driving it, my problem right now is the ai changing lanes.
    in the above that's my current script and i want to use array of array. this is my simple waypoint on the project.
    Annotation 2020-07-02 104859.png

    yes in the above i there 2 array but not array to array, currently i been trying to create array to array script
    but i'm having a little bit problem. so the script above is only make an ai move 1 waypoint only but i want to change so when the ai drive, the ai can change lanes to waypoint 2.

    so im not an expert for an ai for what i see most of an asset the ai car cannot change lanes, and i want to create a scenario where the ai it looks like a real person who's driving and on of the feature is changing lanes so in my mind there's 2 lanes of road so i create 2 waypoint for each road. and in my mind from my script above is to make the 2 waypoint become under 1 array let's call it currentPath so to make it easy to choose which waypoint can the ai change lanes to. so in the update fuction the waypoint 1 become the currentPath[] to make it change lanes. is there a way just simply make the arrays become 1 array or i still need to use the List (Currently Learning) ?
     
  5. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,605
    Ok, at first glance this does seem like a viable approach. However, i can see a few potential problems.
    Let's say your car is at waypoints1[5000] and wants to switch lane. How do you guarantee that waypoints2[5000] is at the exact same position relative to waypoints1[5000], just on the other side of the middle dotted line? You'll need to pay attention to that when placing / generating the waypoints, however this also means that in curves the resolution of one of the paths is higher / lower than the other one.

    A more sophisticated approach in my opinion would be to save the road as a sort of path (straight roads can be defined as a start and end point, while curves could be modelled using bezier curves), then save the progress on a road (or segment) for each car as a percentage value. Now you can calculate its correct progress on the road, and depending on which lane it should drive on, calculate a point some distance to the left or right of that. This also enables you to more easily handle the animation-part of the lane switching, since you can just define a laneChangeInProgress percentage, and lerp between the left and right lane position to smoothly transition. With waypoints this is not as easy, as you'd have to define a fixed target, which may look weird with different velocities, or for example in curves.

    If you want to stick to waypoints, then having two lists (or arrays, if the size is fixed) is fine. If you have an unknown number of lanes, or the number of lanes can switch dynamically at runtime (for example depending on the level), i would save the waypoints as a List<List<GameObject>>, which enables you to add new lanes on demand. I would also probably rename the waypoints1 and 2 arrays to more appropritate "leftLaneWaypoints" and "rightLaneWaypoints", which would already have helped in the understanding of this topic. Properly naming variables is very important, not just for others, but also for you when you return to your code after a couple weeks :)
    Sticking to the waypoint approach, as i mentioned above, you will have to manually make sure / generate the waypoints in a way, such that index x for one array equals the position of index x in the second array, just that they are on opposite sides of the middle line. You will then have to select an n for x+n depending on the given velocity of the car, that approximates a realistic lane-switch for that velocity. You should also think about the resolution of the waypoints, since having a lot of distance between the waypoints may not be a good idea for good looking curves. Using a small resolution works fine, but you may have to travel over one waypoint of distance in a frame (if the car is fast), so you'll need to account for that.

    Hope this helps!
     
    jackvob1 likes this.