How do I properly pick family instances?

0 favourites
  • 14 posts
From the Asset Store
A collection of various zombie characters sprites for creating a 2D platformer or sidescroller game
  • Hello! I am implementing a simple selection box selection behavior. Now, when I try to implement it with this code

    the selection action in the game previews selects only one random family member enclosed in the selection box, as shown by the reduced opacity of the selected object:

    Now, when I add "for each" condition, the selection seems to work:

    As shown here

    Now, If I try to implement the same functionality with objects directly, it does work as expected without the for each addition.

    I was trying to find a proper explanation of family picking in the manual (very unclear explanation ) and on the forum, but I found nothing.

    Thanks in advance for explaining me how family picking works or pointing me the proper explanation on internet.

  • If you put the selection box over all four sprites then they'll all be picked but the function only gets called once. Even though you have four objects picked, only one UID gets sent to the function so only one of them has their opacity changed. That's why you need the 'for each'. You want to call the function for each of the picked objects.

  • Thank you. I have just tested the function calling with normal objects, and it appears that it works differently from other actions. Namely, I can directly reduce the opacity in this way

    This means that the action for setting opacity gets called/executed as many times as the number of picked objects by the condition and for any affected object.

    On the contrary, if I want to use the function to do the similar thing

    the function gets called only once and seemingly for the arbitrary instance.

    Either this is a Construct 2 quirk/inconsistency or I cannot see the purpose behind this behavior. Can you, please, give me more details concerning this subject?

  • Suscribe to this post. Just to add something. When using Function you cannot put a Wait Action inside (of course you're not that you are doing that in your code). It is supose that you cannot use Wait because all the data that the function use can change. Based on this, I can supose that calling "Function" is like some kind of global object that can only have one Instance at the same time, hence your first call to Function works, and then, as the data of the world has changed, Function will not work. But is just speculation.

  • Give this a read: https://www.scirra.com/blog/141/common- ... nd-gotchas, the Unnecessary 'For-each' loops section.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Thank you for this precious link. I think I got it. This is the relevant passage for understanding why function runs only once without a for each condition:

    [quote:3epnghcy]So when should for-each loops be used? Only when what the engine is already doing is not enough. This is usually when you want all the event's actions to run once per instance, rather than just the actions relating to that object. Often this is to get system conditions and actions to run for each instance, which are normally only checked or run once (since there is only ever one system object). For example, if the above event included a system action to subtract from a variable, adding the for-each loop does then change the behavior of the event. Without the explicit loop, the system action only subtracts from the variable once when the event is run, regardless of how many Monster instances were picked by the conditions; with the explicit loop, it also runs the system action once per picked Monster instance, meaning the amount subtracted is proportional to the number of Monsters that are hunting. This can certainly be useful, but the cases when it is truly necessary seem to be less frequent than many users think. Often what the engine does already is enough.

    Ok. In order to explain, I'll make an analogy between the system object and the function object. There is only one instance of the function object of a certain function type (analoguos with: "there is only ever one system object"). Now, when I pick instances of the object in the normal event, the picking is done through the use of the implicit for each loop:

    [quote:3epnghcy]Going back to How Events Work, conditions are tested for each instance, and then actions are run for each instance that met the event's conditions.

    In my case, for each worker that is overlapping the selection box, set worker's opacity to 50. Since all workers which are overlapping the selection box are remembered by the event during the condition testing, an event's action to set worker's opacity to 50 can run for each single worker which satisfies the condition.

    Now, let's go to the function which gets called when the same condition is satisfied. As in the previous case, event's condition filters all instances of worker object type which overlap the selection box. However, no singular instance of the function object type is picked, since actions do not pick anything. Since there is only one instance/object of the function object type, this one gets called only once when the condition is satisfied (= when there is at least one worker overlapping the selection box). That is analoguos to the system actions:

    [quote:3epnghcy]Without the explicit loop, the system action only subtracts from the variable once when the event is run, regardless of how many Monster instances were picked by the conditions;

    So, please do suggest corrections if I got something wrong.

  • Yeah basically the actions of any object that allows you to pick multiple instances (eg. Sprite, Text, Array...) have the implied 'for each' loop.

    [attachment=2:rdag3jv4][/attachment:rdag3jv4]

    This:

    [attachment=1:rdag3jv4][/attachment:rdag3jv4]

    is equivalent to:

    [attachment=0:rdag3jv4][/attachment:rdag3jv4]

  • Thanks! This is quite explanatory! A small question, just in order to test my understanding: In the last script image, function "rotate" will be called only once and with first sprite instance's (according to IID) UID?

  • Yep that's right.

  • I have just tested the picking for arrays and it works in the same way (that is, as for functions). Here, the striked out solution does not give the intended results, while the "for each" works towards the intended goal:

    So, the C2 is consistent in the way it treats single instance object types. However, I find the lack of explanation of this behavior quite a bit misleading for the newcomers. At least, I was confused until now, and I spent at least 50 hours or more debugging the system which I did not understand inspite the fact I have read every relevant page of the manual. Despite the effort, I was still using the striked out manner, without realizing that the action gets executed only once for the first picked instance of the object stated in the condition.

    Ashley, I think that manual page on how events/picking works has to be augmented with the explanation of the picking of single instance object types, like functions, arrays or system objects.

  • What is there to explain? In that event, 'Mouse: on any click' has no effect on the picking at all. It doesn't matter what conditions are above it, you'd always need a for-each loop to push back an array item for each instance.

  • Thank you Ashley for you answer. I am sorry to respond this late, but I did not see your response before (it landed as a first post on the second page, so I somehow did not registered it).

    Well, the mouse condition is irrelevant in this example. It is what follows that I find puzzling for users. At least for me, since i did not understand it and had problems even after reading relevant manual pages and the official blog text about gotchas. Take a look at the following example, please

    The set opacity action works fine (as expected), that is, for each worker. On the other hand, the function does not get executed for each worker. The function in question simply sets the opacity of worker identified with the UID to 50. It is a simple wrapper function for the build-in set opacity action. And yet, it gets executed only once, for the first instance of the worker object. As I see it, it is so, because a function is a single instance object. Every function objects gets picked and since there is only one function object, function gets executed only once.

    I agree that it is a consistent Construct 2 behavior. However, I think that it is not properly documented behavior. Or at least, it should be pointed to as a gotcha. Maybe it is something obvious to you why you should put system condition "for each" in front of function calls and it is redundant to do it before build-in actions. However, I highly doubt that it is for other users which did not participate in the development of C2.

  • I think you have a slight confusion about how actions work. Actions run only once per event, but they run across all objects of that action's 'object type' that were picked by the event conditions. Your event picks all workers which are overlapping the selection box, but only picks one instance of the function object (because there is only one) so it only runs the call function action once, because call function is a function object action, not a worker action. It would be the equivalent of having the function call in a blank sub event, so that's why you need the foreach. It would be different if somehow objects could have functions as instance variables, because then you could call the function as a worker object action and skip the foreach

    It's not so obscure as you may believe, you just need better understanding of the event system

  • Thank you monitz87. I think I finally got it now. This sentence,

    "Actions run only once per event, but they run across all objects of that action's 'object type' that were picked by the event conditions."

    was a a crucial part of your explanation.

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