How do I pick the nearest object in a family? (SOLVED)

0 favourites
  • 11 posts
From the Asset Store
A collection of various zombie characters sprites for creating a 2D platformer or sidescroller game
  • Hello all!

    I am having some trouble using the pick nearest/furthest condition

    I have created 2 families GoodTroops and BadTroops.

    When GoodTroops have a distance over 200 from BadTroops, they run towards them. If they have a distance less than 200 the start shooting at them

    This is what I have so far and for now it only works for the first troops. When I add new ones only 1 troop can shoot at a time.

    Let me know if you have any ideas :)

    Thanks in advance!

  • When you are using a condition like GoodTroops pick nearest to BadTroops.x/y, it will check all instances of GoodTroops, but only one (the first) instance of BadTroops.

    I suggest giving your family a Line Of Sight behavior and using it instead - GoodTroops has LOS to BadTroops.

  • Thanks for the quick reply

    I tried it and it works but there are still 2 issues.

    1. If there are 2 good and 1 bad troops and a new bad troop is created that is closer to the 2nd good troop, this 2nd good troop will not change target but instead it will use the 1st bad troop it saw and move towards it.

    2. How do I use the target LOD in order to shoot the arrow accordingly?

    Thanks :)

  • You should probably use For Each loop if you want to assign a target for every good troop.

    For Each GoodTroops
    GoodTroops has LOS to BadTroops
    BadTroops pick nearest to GoodTroops
     .... GoodTroops Move To BadTroops
    

    But this may not work very well if there are several bad guys roughly at the same distance from the good guy - it will constantly switch targets.

    A proper solution would be saving the target UID in an instance variable on the GoodTroops. Once the target is selected, the good guy will move to it and ignore other targets until its target is destroyed. You can add other conditions to allow changing the selected target, for example, if another enemy has spawned much closer.

    .

    By the way, there is a mistake on your screenshot - in the first action you have Move To (Badtroops.X, Badtroops.X)

  • Thanks again for the detailed answer!

    I tried adding Line of Sight but unfortunately it didn't work as expected.

    But I did it this way:

    Now the targets don't change but when setting the arrow (bullet) angle, it doesn't read the instance var UID so they both shoot the same target.

    It think this is the last problem to solve ;)

    If you want and have time you can check the project, it includes the essentials.

    https://drive.google.com/file/d/1kK5ro2_BAvGguAg_pdxrGU8qzwr8Mlcq/view?usp=sharing

    Thanks dop2000

  • You can't pick a BadTroop by UID, and then pick a different BadTroop by UID in a subevent. Pick By UID only succeeds if the object you're picking is within the group of already-picked object. And since the first Pick BadTroop By UID narrows the picked group of BadTroops down to a singular BadTroop, the second one won't work unless it's the same exact BadTroop that was already picked (that was a tongue twister)

    But what's really messing you up here is the "Pick All GoodTroops." This is resetting the picking done in ForEach. Then you are picking a single GoodTroop, checking if the BadTroop it's targeting is the same BadTroop that was already picked earlier, and then telling all GoodTroops to shoot at it.

    Not only is "PickAllGoodTroops" messing your code up, but you don't need it. You're already looping through each GoodTroop to begin with, so any code in the ForEach will run for every single GoodTroop

  • What you did is not right, the new code has essentially the same problem as in your first comment. If there are several bad troops within 500px from the good guy, the first badtroops instance will be picked as a target. Not necessarily the nearest. And if several good guys see the same bad guys, they will all pick the same one badtroops instance.

    Also, there is no point in using TargetUID variable if you are refreshing targets on every tick. The whole idea is to prevent this - once a goodtroop has a target, it will stick to it and will not be distracted by other targets.

    Picking by comparing distance is the same as using LOS behavior, but the LOS behavior works faster.

    Finally, your events 8 and 9 are also very wrong. They shouldn't be nested inside the loop. I suggest using Timer behavior to shoot a bullet.

    Here is how I would do the whole thing:

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Thank you both for the answers and the example. You put a lot of work into this I really appreciate it :)

    1. It works great but right now there is no way to detect the closest target, so they both shoot the same one.

    2. Also, when a target reaches the range and starts shooting, the other target starts shooting no matter its range even though there is "For Each"

  • To do what you want you mainly have to just rearrange the events you used in your original post:

    for each good
    bad: pick closest to good.x, good.y
    -- distance(good.x, good.y, bad.x, bad.y) < 200
    -- -- good: move toward bad
    -- else
    -- -- good: shoot toward bad

    But like the others suggested it can be good to put a bit more thought into the targeting. For example below I had each bad can be targeted by one good at a time, but that was mainly to prevent the good objects from overlapping over time.

    dropbox.com/s/a9a075lrxu45yjx/targeting_closest.capx

  • Thank you guys! This was really helpful

    I tried both examples and they work as intended :)

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)