How to make an in game block based 3d level editor

Godot Version

4.3

Question

i want to create an in game block based level editor that player is able to create his own levels

you can do this action in editor:

  • place blocks
  • remove blocks
  • transform blocks (multiple blocks can be transformed at time)
  • select blocks and edit them (i want to put some level logic blocks like door or buttons)

but i have searched the net and couldn’t find a tutorial on a block based placement system or an way to make an editor camera (something like the editor that is already in godot)

if you know a way to implement these features in godot 4.3 i would be thankful

1 - for creating a voxel based game like minecraft, you have to use the Zylann godot voxel fork.
the author uses the latest version of godot for it.

it has the block placing, block removing, etc like in minecraft, though it only supports one block in block mode, you can use scenes for other things.

2 - for a 2D block based game like plateup, you have to code it yourself. if the level is not very big you can use scenes for each tile. for something bigger you have to create code that generates geometry, which is more advanced so I would not recommend it if you are a beginner.

thanks , i rather to go with the second way since some of my blocks are functional

but do you have any idea about the editor camera or the grid to place on?
like how i can make an camera that move like the editor camera in godot?
(pressing right mouse button rotates camera and wasd to move it)

I must warn you, using scenes for each tile will not scale well in 3D, you will be limited to a room size or some fixed terrain size, you can’t make a minecraft style game this way, if that’s what you were looking for.

for the camera, rotate it while holding right click, wasd to move it in a direction that you get by multiplying by the basis transform.
it’s just an FPS controller but on a camera instead of on a physical object.

in order to prevent camera tilting, you will need a second node, that has to be a Node3D.


- Node3D
    L Camera3D

Node3D will rotate in Y while Camera3D has to rotate in X and you need to limit the rotation in X to within a min and max angle (in radians).

here’s code from one of my projects:

#on the Node3D

var cursor_mode : bool = false

@export var sensitivity : Vector2
var mouse_look : Vector2
@export var cam_clamp : Vector2

@onready var cam : Camera3D = $Camera3D

@export var SPEED : float = 0.01

var ldirection : Vector3

func _input(event) -> void:
	if event is InputEventMouseMotion and cursor_mode:
		mouse_look = event.relative
		self.rotate_y(mouse_look.x * sensitivity.x)
		cam.rotate_x(mouse_look.y * sensitivity.y)
	if event.is_action_released("ui_cancel"):
		cursor_mode = not cursor_mode
		if cursor_mode:
			DisplayServer.mouse_set_mode(DisplayServer.MOUSE_MODE_CAPTURED)
		else:
			DisplayServer.mouse_set_mode(DisplayServer.MOUSE_MODE_VISIBLE)

func _physics_process(delta) -> void:
	if cursor_mode:
		cam.rotation.x = clamp(cam.rotation.x, cam_clamp.x, cam_clamp.y)
		var input_dir : Vector2 = Input.get_vector("Left", "Right", "Forward", "Backward")
		ldirection = Vector3(input_dir.x, 0, input_dir.y).normalized()
		var direction : Vector3 = (transform.basis * ldirection).normalized()
		if direction:
			global_position += direction * SPEED