I had problems with setting positions on instantiated objects too.
The problem was setting the position while the object wasn't a child of anything.

In snap_block you want to set the position, but the newWall has no parent yet.
I believe the error message !is_inside_tree() shows up only when you try to set global position of unparented objects, but the problem occurs also for setting local positions I guess.

I guess you want to freely position the newWall and when placing it add it as a child to the preview block?
Maybe parent the newWall for placement on the scene tree get_tree().root.add_child(newWall) (or any other node) and then use reparent($PreviewBlock) .
Or set position after adding it as child.

    trizZzle exactly as you described, but this is kinda stupid, that you cant set the position of instanced object before adding it to the parent. If i add it to the root then it will still spawn somewhere in the world and then after the next frame it will be moved to the correct position. What if there is another player moving about the same coordinates, then that player will collide with the object, every time someone adds it to the world.

    I just asked my friend (chatgtp):

    If you want to ensure that the position change is applied immediately, you can call instance.update_transform() after setting the position:

    func newthing():
        var instance = something.instantiate()
        get_tree().root.add_child(instance)
        instance.position = Vector3.ZERO
        instance.update_transform()  # Force an immediate update of the node's transform

    This will force an immediate update of the node's transformation, ensuring that the change in position is applied before the next frame is rendered. Keep in mind that forcing an immediate update can have performance implications, so use it judiciously depending on your specific use case.

    EDIT: I didn't know that positions where updated in the next physics process frame. Good to know.

      It's force_update_transform()

        kuligs2 You're probably right. But often the wrong answer pointed me in the right direction. In this example: There should be a function for this, but maybe it got renamed.

          xyz but unfortunately its still not working

          • xyz replied to this.

            trizZzle it would be nice if godot had the method/function/property preview when you start typing, but unfortunately it shows some of avaliable functions, but not all.

            kuligs2 but unfortunately its still not working

            I didn't expect it to. I just wrote the correct function name.

            Your code looks too complicated. There may be bugs, including ones in parts of code you didn't show.
            If you already have the preview block on the position why just not use it? Or place the block from mousedown event handler.
            Anyway, it'd be best to make a minimal reproduction project and post it for inspection 🙂

              xyz The code is complicated because its code, not a hello world example oneliner. Why do you say im not using the block? Im placing it at the mouse coordinates in the world. The problem is that when i set the position in the world and add it to parent (add_child) the position is not the one that i set/mouse pointer. Its the parent node position, which in my case is a node inside a player instnace.

              Here is the project as is. Run it, press start, then use middle mouse button to activate the building mode then use right mouse button to place the block.
              https://share.apefront.lv/s/4NiGqN6WPEARFzm

              • xyz replied to this.

                kuligs2 The code is complicated because its code

                No, your posted code snippet looks too messy and complicated for what it's supposed to do. Because of that it's easy to lose track of what's happening, which precisely is the case here. You forgot to actually update the position of newly added block:

                Instead of just:

                $PreviewBlock.add_child(newWall)

                Do:

                $PreviewBlock.add_child(newWall)
                snap_block(result, newWall)

                In general, the whole thing should be rewritten to avoid ugly nested if/elses and duplication of parts of code. For example, this needlessly appears twice in a relatively short function:

                var rid_wall = get_rid_from_node(newWall)
                var result = get_ray_results(rid_wall)

                Doing things like this is an open invitation to bugs.

                  xyz i appreciate you giving me your attention and time for helping. The code is what it is, its not a game, its not an art piece, its my way to learn how to do things.

                  When it comes to sequence of events, i would understand that before i show an object in the world, i would set its location, then add object to the world, this makes sense,

                  But apparently godot is ass backwards where you have to add object to world then set its position.

                  Either way it works, changing the 🇦

                  snap_block(result,newWall)
                  $PreviewBlock.add_child(newWall)

                  to

                  $PreviewBlock.add_child(newWall)
                  snap_block(result,newWall)

                  also fyi, if i add the block to world node not player node then the first code works too. So idk..

                  And please explain what you meant with:

                  For example, this needlessly appears twice in a relatively short function:

                  var rid_wall = get_rid_from_node(newWall)
                  var result = get_ray_results(rid_wall)

                  These are different functions that return different values.

                  Given that godot is ass backwards and wont show me values when i put line breaks and try to debug what kind of value i get from methods/properties, i have to define vars pretty much each line to see what kind of value it is.

                  thanks~!

                  • xyz replied to this.

                    kuligs2 You just don't have full understanding of how realtime graphics (including this engine) works. So exercising some restraint before passing the final judgement may be in order 😉

                    The code tidiness is not for winning awards, it primarily serves you, the developer, so you don't end up tangled in unwieldy mess (and puzzling bugs such as this one 🙂)

                    The order of setting the position vs parenting the node is irrelevant as long as the proper position is set before the current frame finishes processing. You didn't do so but instead you updated the position as late as the next frame so you got one frame drawn with non-updated position.

                    As for what I meant about code duplication; your function has two separate blocks of code that do exactly the same thing. It's a sign that control flow can and should be improved.

                    I'd write this whole function as follows, eliminating most of repetition and making it almost twice as short:

                    func new_block_logic():
                    	if not is_preview_block:
                    		remove_preview_block()
                    		return
                    		
                    	var blocks = $PreviewBlock.get_children()
                    	var wall = wall_block.instantiate() if blocks.is_empty() else blocks[0]
                    	if blocks.is_empty():
                    		wall.top_level = true
                    		$PreviewBlock.add_child(wall)
                    
                    	var raycast_result = get_ray_results(get_rid_from_node(wall))
                    	if raycast_result: snap_block(raycast_result, wall)
                    	else: remove_preview_block()

                    The whole thing could architecturally be made even simpler if you don't instantiate the cursor block all the time but instead just keep it alive and hide/show it as needed.