Gameobject Positions within Collections

So, I’ve got a collection that has a number of GameObjects within it. Each of those gameobjects is just used as a waypoint for building a spline.

What I’m finding though is that if I change the position of those gameobjects once the parent collection is added to main.collection – that even though the editor reflects their updated positions, at runtime their position reverts to the position that’s stored in the collection file on disk.

So, the hierarchy is something like:

main–>Spline Collection–>Point1_GO, Point2_GO, Point3_GO, etc.

…if you move those points around in the editor, it works totally fine but when you run they revert to the disk values.

Still new, so trying to wrap my brain around how things are referenced etc. but I could’ve sworn that within a collection you can move the positions of gameobjects and it will override the value stored on disk?

A collection is just a “container” for the game objects, and collections can be moved in the editor, but not at runtime.

If you create a new game object that holds the waypoint game objects, you can move the holder and the child game objects should be moved.

You may need to wait to get world position, however, because it takes a frame for those to update.

Update: I re-read the question, I think maybe it’s because you are using get_position() rather than get_world_position()?

1 Like

I think he’s talking about placing an instance of a collection and modifying its properties in the editor. Unfortunately it’s quite limited and you can’t do that. It seems that the only thing you can change per-collection-instance are Script Properties.

You might think that it works with saved Game Objects, but then you realize that it actually modifies the saved .go file.

That’s right @ross.grams – am trying to place the gameobjects from within the editor. And even without writing any code you can see that the position (while it’s changed in the editor) shows up as 0,0 at runtime (eg. if you attach a sprite to the waypoint gameobject).

So, if that’s the behaviour, my question is – what’s the right way to do this in defold? If I want to place a bunch of waypoint markers on a level, without obviously making unique gameobjects for each waypoint?

That’s…a good question… :grinning_face_with_smiling_eyes:

It sounds like you just need a way to know the IDs of the waypoint objects, wherever they are in your collection hierarchy.

You could use consistent names for them, like your example: “Point1_GO, Point2_GO, Point3_GO, etc.” and construct those names in your script.

-- Something vaguely like this:
local pathObjectURLs = {}
for i=1,pathLength do
	local url = msg.url("Point" .. i .. "_GO")
	table.insert(pathObjectURLs, url)
end

If you may have different numbers of waypoints in your paths then you could use a script property for the length.

Hmm, maybe someone else has a better idea, but that’s the least-clunky way that I can think of at the moment. It depends on if you have other requirements though. Are you going to have multiple sets of waypoints in the same level?

Maybe I’m misinterpreting this, but it’s not possible to avoid using game objects for this. If you want to set the position of something in the editor, and get its position at runtime, then you use a game object. That’s how it works. There isn’t a “smaller” unit that you can do that with.

Ah yes, sorry, let’s see if I can explain it better. Let’s just assume I have an enemy gameobject…it’s got a sprite and a collision object and a script. And I want to place those enemies around my level in pre-set locations via the editor. It seems like I could do this by basically creating new gameobjects and manually adding them to the level collection? But from what I’m discovering, I can’t just keep doing “Add GameObject File” and adding them and placing them around the level or they just revert to whatever position is saved in the GO file is what I’m seeing. Even if I place them within a collection. It seems like whatever position is in the GO file is the position it’s going to have a runtime.

Should they be collections instead of GameObjects? Or am I fundamentally misunderstanding something about the model?

Is the level collection placed within another collection? I think you need to open the level collection by itself and edit that.

2 Likes

Yeah it would be within the main collection. But here’s a tiny sandbox example I put together that illustrates what I’m trying to do. I even tried switch to collections for everything and still getting the same behaviour so I must just be doing it wrong.

You can see the “points” that are placed in the editor (those dots could be enemies, could be whatever) and they are in the correct locations, but if you run this, they do not appear in those locations, they appear at the origin. Which, in the “spline.collection” file that is on disk, that is the location of those 4 points (0,0). If I edit their position inside the spline.collection, sure, it works, but then I have to make a duplicate collection for every instance of the spline I want? That doesn’t seem right.

There must be a way to create re-usable/re-locatable “widgets” like this I would think? It feels like I’m just missing some basic concept with the engine because this is a really common pattern.

Have you tried what Klear suggested?

Here is a little test I did.
I made a Sprite collection and attached it to a main collection:


ran it:

moved the gos in the main collection:

ran it:

Bingo, that’s what you report, the position change is not reflected when running
But when I move the gos in the sprite collection:

The positions are updated when running:

1 Like

Sorry, just saw you already did that!
I probably don’t understand your use-case, but why don’t you just put all your way-points into one collection. I see you have one for each point now.

Hey - yeah I originally had all the points just as gameobjects inside the spline collection and made a collection for each point in an attempt to get it to work the way I want. Same behaviour (as your example shows).

The issue I have is that the way it works it seems like for every spline (or it could be anything I want to place on a level) that I’d have to make a new version of that with different positions.

Plus I can’t set the positions in the main level I have to go do it inside the collection file. That makes it very tedious with a lot of duplication.

I’m clearly fighting the “proper” way to do this (which still isn’t clear to me) but it’s really surprising to me that I can’t instantiate discrete instances of a collection in the editor and then modify them independently. Especially since the editor reflects that I’ve changed the original position it just doesn’t use that changed position.

Even with the example given if I want two different splines I have to make two distinct spline collections and I can’t actually edit them within the context of the level.

So it seems to me that to get this workflow (which is a not a strange workflow) I’d basically have to build my own level editor and use a factory to instantiate the spline collection at runtime with positions stored by my custom level editor and I can’t really use the regular editor to edit levels.

Which seems odd and a shame because the editor is awesome.

Hm, I think that’s just how it works, you set the position in the collection the gos are situated. If you move them about in another collection, this will not be reflected when running as far I know.
Assuming I understand correctly what you try to achieve, I would do this:
make a collection for each of your levels and add your waypoints and position them there. You don’t need to put those gos themselves into yet another collection each.
Collection 1:


or maybe like so if you like this better:

Collection 2:

And so on

Then put them into the main collection:

Then manipulate your objects in a script at your heart’s content if you like to do so.

1 Like

Thanks @raetia - appreciate the help. I see how it works and realize that this is just the way it works.

Basically just need to make new spline collections for each instance.

Seems a shame that there’s no way to make a reusable spline “widget” (or any other type of widget) where you can just drop it into the level and manipulate because it’s a new instance and not modifying the original “prototype”.

Still thx for the good explanation of how it works!

Hm, at least that’s how I would approach this - always assuming I understood correctly what you like to do. Since you speak of a “prototype”, might a factory be of use: Factory component manual. I never use them, so can’t tell you more about them.

1 Like

Why do you want them in their own collection? You seem really firm on this.

2 Likes

Hey – ok, thanks to everyone who replied to explain this to me, it really helped me get a better grasp on how these things work. For @ross.grams – I wasn’t really set on having it in a collection, I just didn’t understand how it worked and that was my intuition. But now that I know how it works, I think I have a solution that works for me. Here’s what I did:

Basically, you can see that I have a Point.go that has a sprite attached to it already so you can see it in the editor view. I can drop as many of these waypoint GOs as I want in the main.collection or level collection and move them around and it all works. Then, you can see I just have a Spline.go that I can drop in as many of these as I like and what I do is just put in the names of the relevant waypoints for that particular spline (which in my case defines a path) and then the code generates the spline based on those waypoints.

This way, everything can be edited inside the level view without having to open up separate collections, and there’s no manual creation of anything (adding sprites, etc.) – you just dump a bunch of the gameobjects in there, and then connect them in that list of points. Works perfectly!

Thanks again for all the help, still new to this engine but I love the simplicity and how streamlined everything is, but still learning the “right” way to do things.

5 Likes

I would just like to add that I ran into this under similar circumstances. It’s not a blocker, but it’s fairly difficult to realise what you’re doing wrong when you run into it the first time.

2 Likes