How do I properly pick family instances?

Get help using Construct 2

Post » Sat May 03, 2014 9:22 pm

Message: Lunarovich is not yet permitted to post plain text URLS (300 rep required). 1 URLS removed. Why?
Hello! I am implementing a simple selection box selection behavior. Now, when I try to implement it with this code

Image

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:

Image

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

Image

As shown here

Image

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.
B
6
S
2
Posts: 64
Reputation: 576

Post » Sat May 03, 2014 10:42 pm

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.
B
55
S
29
G
19
Posts: 1,520
Reputation: 25,670

Post » Sat May 03, 2014 11:21 pm

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

Image

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

Image

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?
B
6
S
2
Posts: 64
Reputation: 576

Post » Sun May 04, 2014 10:36 am

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.
B
10
S
2
G
1
Posts: 48
Reputation: 1,265

Post » Sun May 04, 2014 12:48 pm

Give this a read: https://www.scirra.com/blog/141/common- ... nd-gotchas, the Unnecessary 'For-each' loops section.
ImageImageImage
B
71
S
22
G
248
Posts: 3,758
Reputation: 138,067

Post » Sun May 04, 2014 2:24 pm

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:

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:

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:

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.
B
6
S
2
Posts: 64
Reputation: 576

Post » Sun May 04, 2014 5:18 pm

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

foreach.png


This:
impliedForEach1.PNG

is equivalent to:
impliedForEach2.PNG
You do not have the required permissions to view the files attached to this post.
B
55
S
29
G
19
Posts: 1,520
Reputation: 25,670

Post » Sun May 04, 2014 5:31 pm

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?
B
6
S
2
Posts: 64
Reputation: 576

Post » Sun May 04, 2014 5:54 pm

Yep that's right.
B
55
S
29
G
19
Posts: 1,520
Reputation: 25,670

Post » Fri May 09, 2014 5:44 am

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:

Image

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.
B
6
S
2
Posts: 64
Reputation: 576

Next

Return to How do I....?

Who is online

Users browsing this forum: Felipiwi and 21 guests