- Edited
The idea is such that when toggle build mode, then you cast a ray that hits the world object, if result then place instnace (child) at the result.position.
At the moment i have a player node where i place the preview block inside the previewNode.
Player has a script with functions for block preview:
func new_block_logic():
if is_preview_block:
# place prieview block in player node
var blocks = $PreviewBlock.get_children()
if blocks.is_empty():
# if there are no preview blocks in the node
var newWall:Node3D = wall_block.instantiate()
var rid_wall = get_rid_from_node(newWall)
var result = get_ray_results(rid_wall)
if result:
snap_block(result,newWall)
newWall.top_level=true
$PreviewBlock.add_child(newWall)
else:
remove_preview_block()
else:
var newWall:Node3D = blocks[0]
var rid_wall = get_rid_from_node(newWall)
var result = get_ray_results(rid_wall)
if result:
snap_block(result, newWall)
else:
remove_preview_block()
else:
# delete prieview block
remove_preview_block()
pass
func snap_block(result, block):
if result.collider.is_in_group("j_block"):
pass
else:
block.position = result.position
pass
func get_ray_results(rid_wall):
var space_state = get_world_3d().direct_space_state
var cam = cameraNode
var mousepos = get_viewport().get_mouse_position()
var origin = cam.project_ray_origin(mousepos)
var RAY_LENGTH = 1000.0
var end = origin + cam.project_ray_normal(mousepos) * RAY_LENGTH
var query = PhysicsRayQueryParameters3D.create(origin, end)
query.collide_with_areas = true
if rid_wall:
query.exclude = [self, rid_wall]
else:
query.exclude = [self]
return space_state.intersect_ray(query)
func get_rid_from_node(node:Node3D):
var col = node.find_child("StaticBody3D",true) #.get_node("CollisionShape3D")
if col:
var rid = col.get_rid()
return rid
As you can see in new_block_logic()
if the ray hit gets results then i get new instance of block scene and then i set that block position to the result position and i set the top_level
to true and then i add it as child to the preview node, but when i run the game, and activate the build mode, the block appears to be added at default coordinate and when the next frame comes the position is set to the correct position.
How to can i fix this so that the block i want to add is set to the right position before i add it to scene??
Video in godot 4.1.3
video in godot 4.2 rc2
To me it seems like the set top level to true is not working on the frame 0 when you add child to node.