Picking Objects does not work inside functions

Bugs will be moved here once resolved.

Post » Wed Oct 11, 2017 6:57 pm

newt wrote:On the other hand, calling functions to modify instances is like nightmare fuel.


Not being able to modify instances with reusable code is pretty much being left with limited useless functions, sadly.

Any other professional engine let you instantiate and modify instances in the same tick at any point of the code as long as you call them after instantiating. That`s why it is a bad design of C2. For me it is a bug because that`s not how functions should work but it seems that it is just a terrible limitation of the engine
B
7
S
2
Posts: 31
Reputation: 947

Post » Wed Oct 11, 2017 8:06 pm

Might want to check out some of the other features such as the "on created" trigger, as well as containers.
Image ImageImage
B
171
S
50
G
180
Posts: 8,394
Reputation: 113,982

Post » Wed Oct 11, 2017 8:29 pm

For a game creation tool geared toward beginners this is a hard to understand and hard to explain quirk of picking. It has everything to do with when newly created objects are pickable.

What Construct does is keep track of three seperate lists:
object list (OL)
new object list (NOL)
selected object list (SOL)

Before a event starts the SOL is the same as OL, and the conditions do picking that changes the SOL. So far so good, that's easy to understand.

When an object gets created it isn't added to the OL right away. Instead it's added to the NOL and the SOL is set to just that new object. The NOL is only added to the OL at the end of a top-level event. Bear in mind a function isn't a top-level event.

Also the pick by uid condition is special in that it can pick an object at anytime after it was created. This is the simplest way to just ignore this picking mess.

Anyways that's a bit hard to follow so let's consider the examples in your capx.

Test1
Code: Select all
global spawnedCard=0

on "spawnCard"
--- create card
--- set card.carduid to card.uid
--- return card.uid

on "setScale"
pick by comparison card.carduid = param(0)
--- set card scale

start of layout
--- call "spawnCard"
--- set spawnedCard to returnValue
--- call "setScale" (spawnedcard, 0.1)


Code: Select all
Start of layout is triggered and the lists are:
OL=[], NOL=[], SOL=[]

spawncard is called
OL=[], NOL=[], SOL=[]

card is created and before the function exits:
OL=[], NOL=[card0], SOL=[card0]

Back in the start of layout event
OL=[], NOL=[card0], SOL=[]

setscale is called
OL=[], NOL=[card0], SOL=[]

it tries to pick the card with pick by comparison condition but since the SOL is empty it fails.  The solution here would be to use the "pick by uid" condition.

the function returns and the "start of layout" ends and since it's top-level the NOL is moved into the OL:
OL=[card0], NOL=[], SOL=[] 


Test2
Code: Select all
on setscale
pick card by comparison
--- set card scale

start of layout
--- create card
--- call setscale


Code: Select all
start of layout triggered
OL=[], NOL=[], SOL=[]

new card created
OL=[], NOL=[card0], SOL=[card0]

setscale function called
OL=[], NOL=[card0], SOL=[]

pick by comparison attempted.  No objects in SOL to pick from so it fails. Again using "pick by uid" would fix this.

function returns and start of layout ends:
OL=[card0], NOL=[], SOL=[]


test3
Code: Select all
Start of layout
--- create card

trigger once
pick by comparison
--- set card scale


Code: Select all
Start of layout triggered
OL=[], NOL=[], SOL=[]

new card created
OL=[], NOL=[card0], SOL=[card0]

start of layout ends
OL=[card0], NOL=[], SOL=[]

trigger once starts.  The SOL is set to the OL.
OL=[card0], NOL=[], SOL=[card0]

card is picked by comparison.  This one works because the card we want is in the sol.



The examples in your capx are fixed as i mentioned by using the "pick by uid" condition instead of "pick by comparison". Again that's because "pick by uid" is special in that regaurd in picking newly created objects. There are other situations where this picking is annoying to deal with, but in this case it's trivial.

This behavior is a heavily ingrained part of how events work so I wouldn't count on it changing. Also i do believe it was intentional to avoid some bugs, not to mention i'm not sure a better solution as it relates to the picking system is available. I don't think something like this is very nice for beginners though.
B
94
S
33
G
114
Posts: 5,359
Reputation: 73,779

Post » Tue Oct 17, 2017 3:33 pm

Thanks for the clear explanation @R0J0hound. This is a known quirk of the engine so closing as won't fix. FWIW, the reason we can't update the object list directly is because in many cases it would crash or deoptimise the engine. The quirk seems like a less bad option. Construct 3 also has a "pick last created" which helps work around it.
Scirra Founder
B
399
S
236
G
89
Posts: 24,543
Reputation: 195,430

Previous

Return to Closed bugs

Who is online

Users browsing this forum: No registered users and 3 guests