Selaa lähdekoodia

Add block placement preview to Voxel demo, improve debug display (#1190)

- Allow placing/breaking blocks when further away (up to 5 blocks instead of 4).
- Add a background to the debug display to improve readability on bright backgrounds.
- Simplify coordinate display using the `%v` placeholder available in 4.3 onwards.
Hugo Locurcio 3 kuukautta sitten
vanhempi
commit
a88ca219b8
4 muutettua tiedostoa jossa 44 lisäystä ja 28 poistoa
  1. 5 25
      3d/voxel/menu/debug.gd
  2. 8 1
      3d/voxel/player/player.gd
  3. 28 2
      3d/voxel/player/player.tscn
  4. 3 0
      3d/voxel/world/world.tscn

+ 5 - 25
3d/voxel/menu/debug.gd

@@ -8,31 +8,11 @@ func _process(_delta: float) -> void:
 	if Input.is_action_just_pressed(&"debug"):
 		visible = not visible
 
-	text = "Position: " + _vector_to_string_appropriate_digits(player.transform.origin)
-	text += "\nEffective render distance: " + str(voxel_world.effective_render_distance)
-	text += "\nLooking: " + _cardinal_string_from_radians(player.transform.basis.get_euler().y)
-	text += "\nMemory: " + "%3.0f" % (OS.get_static_memory_usage() / 1048576.0) + " MiB"
-	text += "\nFPS: " + String.num_uint64(Engine.get_frames_per_second())
-
-
-# Avoids the problem of showing more digits than needed or available.
-func _vector_to_string_appropriate_digits(vector: Vector3) -> String:
-	var factors: Array[int] = [1000, 1000, 1000]
-	for i in 3:
-		if abs(vector[i]) > 4096:
-			@warning_ignore("integer_division")
-			factors[i] = factors[i] / 10
-			if abs(vector[i]) > 65536:
-				@warning_ignore("integer_division")
-				factors[i] = factors[i] / 10
-				if abs(vector[i]) > 524288:
-					@warning_ignore("integer_division")
-					factors[i] = factors[i] / 10
-
-	return "(" + \
-			str(round(vector.x * factors[0]) / factors[0]) + ", " + \
-			str(round(vector.y * factors[1]) / factors[1]) + ", " + \
-			str(round(vector.z * factors[2]) / factors[2]) + ")"
+	text = "Position: %.1v" % player.transform.origin \
+			+ "\nEffective render distance: " + str(voxel_world.effective_render_distance) \
+			+ "\nLooking: " + _cardinal_string_from_radians(player.transform.basis.get_euler().y) \
+			+ "\nMemory: " + "%3.0f" % (OS.get_static_memory_usage() / 1048576.0) + " MiB" \
+			+ "\nFPS: %d" % Engine.get_frames_per_second()
 
 
 # Expects a rotation where 0 is North, on the range -PI to PI.

+ 8 - 1
3d/voxel/player/player.gd

@@ -20,6 +20,7 @@ var _selected_block := 6
 @onready var selected_block_texture: TextureRect = $SelectedBlock
 @onready var voxel_world: Node = $"../VoxelWorld"
 @onready var crosshair: CenterContainer = $"../PauseMenu/Crosshair"
+@onready var aim_preview: MeshInstance3D = $AimPreview
 
 
 func _ready() -> void:
@@ -54,6 +55,9 @@ func _process(_delta: float) -> void:
 
 	# Block breaking/placing.
 	if crosshair.visible and raycast.is_colliding():
+		aim_preview.visible = true
+		var ray_current_block_position := Vector3i((ray_position - ray_normal / 2).floor())
+		aim_preview.global_position = Vector3(ray_current_block_position) + Vector3(0.5, 0.5, 0.5)
 		var breaking := Input.is_action_just_pressed(&"break")
 		var placing := Input.is_action_just_pressed(&"place")
 		# Either both buttons were pressed or neither are, so stop.
@@ -61,11 +65,14 @@ func _process(_delta: float) -> void:
 			return
 
 		if breaking:
-			var block_global_position := Vector3i((ray_position - ray_normal / 2).floor())
+			var block_global_position := ray_current_block_position
 			voxel_world.set_block_global_position(block_global_position, 0)
 		elif placing:
+			# Calculate the position of the block to be placed.
 			var block_global_position := Vector3i((ray_position + ray_normal / 2).floor())
 			voxel_world.set_block_global_position(block_global_position, _selected_block)
+	else:
+		aim_preview.visible = false
 
 
 func _physics_process(delta: float) -> void:

+ 28 - 2
3d/voxel/player/player.tscn

@@ -1,4 +1,4 @@
-[gd_scene load_steps=6 format=3 uid="uid://1s4asqpay67m"]
+[gd_scene load_steps=10 format=3 uid="uid://1s4asqpay67m"]
 
 [ext_resource type="Script" uid="uid://rm45k07vw817" path="res://player/player.gd" id="1"]
 [ext_resource type="Texture2D" uid="uid://d3f34krqfgdjd" path="res://world/textures/texture_sheet.png" id="2"]
@@ -13,6 +13,27 @@ radius = 0.375
 atlas = ExtResource("2")
 region = Rect2(0, 0, 64, 64)
 
+[sub_resource type="Gradient" id="Gradient_rkbax"]
+offsets = PackedFloat32Array(0.952381, 1)
+colors = PackedColorArray(0, 0, 0, 0.0941176, 0, 0, 0, 1)
+
+[sub_resource type="GradientTexture2D" id="GradientTexture2D_g1dw6"]
+gradient = SubResource("Gradient_rkbax")
+width = 256
+height = 256
+fill = 2
+fill_from = Vector2(0.5, 0.5)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yw30f"]
+transparency = 1
+shading_mode = 0
+albedo_texture = SubResource("GradientTexture2D_g1dw6")
+uv1_scale = Vector3(3, 2, 1)
+
+[sub_resource type="BoxMesh" id="BoxMesh_qjkh3"]
+material = SubResource("StandardMaterial3D_yw30f")
+size = Vector3(1.001, 1.001, 1.001)
+
 [node name="Player" type="CharacterBody3D"]
 collision_layer = 0
 script = ExtResource("1")
@@ -31,7 +52,7 @@ near = 0.02
 far = 1000.0
 
 [node name="RayCast3D" type="RayCast3D" parent="Head"]
-target_position = Vector3(0, 0, -4)
+target_position = Vector3(0, 0, -5)
 
 [node name="SelectedBlock" type="TextureRect" parent="."]
 texture_filter = 1
@@ -48,3 +69,8 @@ grow_horizontal = 0
 grow_vertical = 0
 texture = SubResource("2")
 expand_mode = 1
+
+[node name="AimPreview" type="MeshInstance3D" parent="."]
+top_level = true
+visible = false
+mesh = SubResource("BoxMesh_qjkh3")

+ 3 - 0
3d/voxel/world/world.tscn

@@ -37,6 +37,9 @@ offset_bottom = -20.0
 grow_horizontal = 2
 grow_vertical = 2
 theme = ExtResource("7")
+theme_override_colors/font_shadow_color = Color(0, 0, 0, 0.501961)
+theme_override_constants/shadow_offset_x = 2
+theme_override_constants/shadow_offset_y = 2
 theme_override_font_sizes/font_size = 48
 script = ExtResource("6")