mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2025-12-16 13:30:07 +01:00
Use static typing in all demos (#1063)
This leads to code that is easier to understand and runs faster thanks to GDScript's typed instructions. The untyped declaration warning is now enabled on all projects where type hints were added. All projects currently run without any untyped declration warnings. Dodge the Creeps and Squash the Creeps demos intentionally don't use type hints to match the documentation, where type hints haven't been adopted yet (given its beginner focus).
This commit is contained in:
@@ -1,9 +1,23 @@
|
||||
extends Node3D
|
||||
|
||||
func _ready():
|
||||
## Camera idle scale effect intensity.
|
||||
const CAMERA_IDLE_SCALE = 0.005
|
||||
|
||||
var counter := 0.0
|
||||
@onready var camera_base_rotation: Vector3 = $Camera3D.rotation
|
||||
|
||||
func _ready() -> void:
|
||||
# Clear the viewport.
|
||||
var viewport = $SubViewport
|
||||
$SubViewport.set_clear_mode(SubViewport.CLEAR_MODE_ONCE)
|
||||
var viewport: SubViewport = $SubViewport
|
||||
viewport.render_target_clear_mode = SubViewport.CLEAR_MODE_ONCE
|
||||
|
||||
# Retrieve the texture and set it to the viewport quad.
|
||||
$ViewportQuad.material_override.albedo_texture = viewport.get_texture()
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
# Animate the camera with an "idle" animation.
|
||||
counter += delta
|
||||
$Camera3D.rotation.x = camera_base_rotation.y + cos(counter) * CAMERA_IDLE_SCALE
|
||||
$Camera3D.rotation.y = camera_base_rotation.y + sin(counter) * CAMERA_IDLE_SCALE
|
||||
$Camera3D.rotation.z = camera_base_rotation.y + sin(counter) * CAMERA_IDLE_SCALE
|
||||
|
||||
@@ -66,9 +66,8 @@ tonemap_white = 2.0
|
||||
script = ExtResource("1_b8rgl")
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0.6)
|
||||
fov = 62.0
|
||||
near = 0.1
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.35, 0.5)
|
||||
fov = 60.0
|
||||
|
||||
[node name="ViewportQuad" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(2, 0, 0, 0, 0, -1.333, 0, 1, 0, 0, 1.2, -4.25)
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
extends Node2D
|
||||
|
||||
const PAD_SPEED = 150
|
||||
const INITIAL_BALL_SPEED = 80
|
||||
const INITIAL_BALL_SPEED = 80.0
|
||||
|
||||
var ball_speed = INITIAL_BALL_SPEED
|
||||
var screen_size = Vector2(640, 400)
|
||||
var ball_speed := INITIAL_BALL_SPEED
|
||||
var screen_size := Vector2(640, 400)
|
||||
|
||||
# Default ball direction.
|
||||
var direction = Vector2.LEFT
|
||||
var pad_size = Vector2(8, 32)
|
||||
var direction := Vector2.LEFT
|
||||
var pad_size := Vector2(8, 32)
|
||||
|
||||
@onready var ball = $Ball
|
||||
@onready var left_paddle = $LeftPaddle
|
||||
@onready var right_paddle = $RightPaddle
|
||||
@onready var ball: Sprite2D = $Ball
|
||||
@onready var left_paddle: Sprite2D = $LeftPaddle
|
||||
@onready var right_paddle: Sprite2D = $RightPaddle
|
||||
|
||||
func _ready():
|
||||
screen_size = get_viewport_rect().size # Get actual size.
|
||||
func _ready() -> void:
|
||||
screen_size = get_viewport_rect().size # Get actual size.
|
||||
pad_size = left_paddle.get_texture().get_size()
|
||||
|
||||
|
||||
func _process(delta):
|
||||
func _process(delta: float) -> void:
|
||||
# Get ball position and pad rectangles.
|
||||
var ball_pos = ball.get_position()
|
||||
var left_rect = Rect2(left_paddle.get_position() - pad_size * 0.5, pad_size)
|
||||
var right_rect = Rect2(right_paddle.get_position() - pad_size * 0.5, pad_size)
|
||||
var ball_pos := ball.get_position()
|
||||
var left_rect := Rect2(left_paddle.get_position() - pad_size * 0.5, pad_size)
|
||||
var right_rect := Rect2(right_paddle.get_position() - pad_size * 0.5, pad_size)
|
||||
|
||||
# Integrate new ball postion.
|
||||
ball_pos += direction * ball_speed * delta
|
||||
@@ -48,7 +48,7 @@ func _process(delta):
|
||||
ball.set_position(ball_pos)
|
||||
|
||||
# Move left pad.
|
||||
var left_pos = left_paddle.get_position()
|
||||
var left_pos := left_paddle.get_position()
|
||||
|
||||
if left_pos.y > 0 and Input.is_action_pressed(&"left_move_up"):
|
||||
left_pos.y += -PAD_SPEED * delta
|
||||
@@ -58,7 +58,7 @@ func _process(delta):
|
||||
left_paddle.set_position(left_pos)
|
||||
|
||||
# Move right pad.
|
||||
var right_pos = right_paddle.get_position()
|
||||
var right_pos := right_paddle.get_position()
|
||||
if right_pos.y > 0 and Input.is_action_pressed(&"right_move_up"):
|
||||
right_pos.y += -PAD_SPEED * delta
|
||||
if right_pos.y < screen_size.y and Input.is_action_pressed(&"right_move_down"):
|
||||
|
||||
@@ -17,6 +17,10 @@ run/main_scene="res://2d_in_3d.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[input]
|
||||
|
||||
left_move_up={
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
extends Node2D
|
||||
|
||||
var viewport_initial_size = Vector2()
|
||||
@onready var viewport: SubViewport = $SubViewport
|
||||
@onready var viewport_initial_size: Vector2i = viewport.size
|
||||
@onready var viewport_sprite: Sprite2D = $ViewportSprite
|
||||
|
||||
@onready var viewport = $SubViewport
|
||||
@onready var viewport_sprite = $ViewportSprite
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
$AnimatedSprite2D.play()
|
||||
get_viewport().size_changed.connect(_root_viewport_size_changed)
|
||||
viewport_initial_size = viewport.size
|
||||
|
||||
|
||||
# Called when the root's viewport size changes (i.e. when the window is resized).
|
||||
# This is done to handle multiple resolutions without losing quality.
|
||||
func _root_viewport_size_changed():
|
||||
func _root_viewport_size_changed() -> void:
|
||||
# The viewport is resized depending on the window height.
|
||||
# To compensate for the larger resolution, the viewport sprite is scaled down.
|
||||
viewport.size = Vector2.ONE * get_viewport().size.y
|
||||
|
||||
@@ -17,6 +17,10 @@ run/main_scene="res://3d_in_2d.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
extends Node
|
||||
## A simple script that rotates the model.
|
||||
|
||||
# A simple script to rotate the model.
|
||||
@onready var model = $Model
|
||||
@onready var model: Node3D = $Model
|
||||
|
||||
func _process(delta):
|
||||
model.rotate_y(delta * 0.7)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
model.rotation.y += delta * 0.7
|
||||
|
||||
@@ -108,7 +108,7 @@ mesh = SubResource("1")
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(0.877582, 0.229849, -0.420736, 0, 0.877582, 0.479426, 0.479426, -0.420736, 0.770151, -1.68294, 2.25571, 3.0806)
|
||||
fov = 74.0
|
||||
fov = 60.0
|
||||
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, 2, 1)
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
extends Control
|
||||
|
||||
## The 3D viewport's shrink factor. For instance, 1 is full resolution,
|
||||
## 2 is half resolution and 4 is quarter resolution. Lower values look
|
||||
## sharper but are slower to render.
|
||||
var scale_factor := 1
|
||||
|
||||
# The 3D viewport's shrink factor. For instance, 1 is full resolution,
|
||||
# 2 is half resolution and 4 is quarter resolution. Lower values look
|
||||
# sharper but are slower to render.
|
||||
var scale_factor = 1
|
||||
var filter_mode = Viewport.SCALING_3D_MODE_BILINEAR
|
||||
var filter_mode := Viewport.SCALING_3D_MODE_BILINEAR
|
||||
|
||||
@onready var viewport = get_tree().root
|
||||
@onready var scale_label = $VBoxContainer/Scale
|
||||
@onready var filter_label = $VBoxContainer/Filter
|
||||
@onready var viewport: Window = get_tree().root
|
||||
@onready var scale_label: Label = $VBoxContainer/Scale
|
||||
@onready var filter_label: Label = $VBoxContainer/Filter
|
||||
|
||||
|
||||
func _ready():
|
||||
viewport.scaling_3d_mode = Viewport.SCALING_3D_MODE_BILINEAR
|
||||
func _ready() -> void:
|
||||
viewport.scaling_3d_mode = filter_mode
|
||||
|
||||
|
||||
func _unhandled_input(event):
|
||||
if event.is_action_pressed("cycle_viewport_resolution"):
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed(&"cycle_viewport_resolution"):
|
||||
scale_factor = wrapi(scale_factor + 1, 1, 5)
|
||||
viewport.scaling_3d_scale = 1.0 / scale_factor
|
||||
scale_label.text = "Scale: %3.0f%%" % (100.0 / scale_factor)
|
||||
|
||||
if event.is_action_pressed("toggle_filtering"):
|
||||
if event.is_action_pressed(&"toggle_filtering"):
|
||||
filter_mode = wrapi(filter_mode + 1, Viewport.SCALING_3D_MODE_BILINEAR, Viewport.SCALING_3D_MODE_MAX) as Viewport.Scaling3DMode
|
||||
viewport.scaling_3d_mode = filter_mode
|
||||
filter_label.text = (
|
||||
|
||||
@@ -21,6 +21,10 @@ run/main_scene="res://hud.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
extends Node3D
|
||||
|
||||
# Handle the motion of both player cameras as well as communication with the
|
||||
# SplitScreen shader to achieve the dynamic split screen effet
|
||||
#
|
||||
@@ -19,22 +18,22 @@ extends Node3D
|
||||
# depending on the distance between players. If false, the thickness will
|
||||
# be constant and equal to split_line_thickness
|
||||
|
||||
@export var max_separation: float = 20.0
|
||||
@export var split_line_thickness: float = 3.0
|
||||
@export var split_line_color: Color = Color.BLACK
|
||||
@export var adaptive_split_line_thickness: bool = true
|
||||
@export var max_separation := 20.0
|
||||
@export var split_line_thickness := 3.0
|
||||
@export var split_line_color := Color.BLACK
|
||||
@export var adaptive_split_line_thickness := true
|
||||
|
||||
@onready var player1 = $"../Player1"
|
||||
@onready var player2 = $"../Player2"
|
||||
@onready var view = $View
|
||||
@onready var viewport1 = $Viewport1
|
||||
@onready var viewport2 = $Viewport2
|
||||
@onready var camera1 = viewport1.get_node(^"Camera1")
|
||||
@onready var camera2 = viewport2.get_node(^"Camera2")
|
||||
@onready var player1: CharacterBody3D = $"../Player1"
|
||||
@onready var player2: CharacterBody3D = $"../Player2"
|
||||
@onready var view: TextureRect = $View
|
||||
@onready var viewport1: SubViewport = $Viewport1
|
||||
@onready var viewport2: SubViewport = $Viewport2
|
||||
@onready var camera1: Camera3D = viewport1.get_node(^"Camera1")
|
||||
@onready var camera2: Camera3D = viewport2.get_node(^"Camera2")
|
||||
|
||||
var viewport_base_height = ProjectSettings.get_setting("display/window/size/viewport_height")
|
||||
var viewport_base_height := int(ProjectSettings.get_setting("display/window/size/viewport_height"))
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
_on_size_changed()
|
||||
_update_splitscreen()
|
||||
|
||||
@@ -44,15 +43,15 @@ func _ready():
|
||||
view.material.set_shader_parameter("viewport2", viewport2.get_texture())
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
func _process(_delta: float) -> void:
|
||||
_move_cameras()
|
||||
_update_splitscreen()
|
||||
|
||||
|
||||
func _move_cameras():
|
||||
var position_difference = _compute_position_difference_in_world()
|
||||
func _move_cameras() -> void:
|
||||
var position_difference := _get_position_difference_in_world()
|
||||
|
||||
var distance = clamp(_compute_horizontal_length(position_difference), 0, max_separation)
|
||||
var distance := clampf(_get_horizontal_length(position_difference), 0, max_separation)
|
||||
|
||||
position_difference = position_difference.normalized() * distance
|
||||
|
||||
@@ -63,37 +62,38 @@ func _move_cameras():
|
||||
camera2.position.z = player2.position.z - position_difference.z / 2.0
|
||||
|
||||
|
||||
func _update_splitscreen():
|
||||
var screen_size = get_viewport().get_visible_rect().size
|
||||
var player1_position = camera1.unproject_position(player1.position) / screen_size
|
||||
var player2_position = camera2.unproject_position(player2.position) / screen_size
|
||||
func _update_splitscreen() -> void:
|
||||
var screen_size := get_viewport().get_visible_rect().size
|
||||
var player1_position := camera1.unproject_position(player1.position) / screen_size
|
||||
var player2_position := camera2.unproject_position(player2.position) / screen_size
|
||||
|
||||
var thickness
|
||||
var thickness := 0.0
|
||||
if adaptive_split_line_thickness:
|
||||
var position_difference = _compute_position_difference_in_world()
|
||||
var distance = _compute_horizontal_length(position_difference)
|
||||
var position_difference := _get_position_difference_in_world()
|
||||
var distance := _get_horizontal_length(position_difference)
|
||||
thickness = lerpf(0, split_line_thickness, (distance - max_separation) / max_separation)
|
||||
thickness = clampf(thickness, 0, split_line_thickness)
|
||||
else:
|
||||
thickness = split_line_thickness
|
||||
|
||||
view.material.set_shader_parameter("split_active", _get_split_state())
|
||||
view.material.set_shader_parameter("split_active", _is_split_state())
|
||||
view.material.set_shader_parameter("player1_position", player1_position)
|
||||
view.material.set_shader_parameter("player2_position", player2_position)
|
||||
view.material.set_shader_parameter("split_line_thickness", thickness)
|
||||
view.material.set_shader_parameter("split_line_color", split_line_color)
|
||||
|
||||
|
||||
# Split screen is active if players are too far apart from each other.
|
||||
# Only the horizontal components (x, z) are used for distance computation
|
||||
func _get_split_state():
|
||||
var position_difference = _compute_position_difference_in_world()
|
||||
var separation_distance = _compute_horizontal_length(position_difference)
|
||||
## Returns `true` if split screen is active (which occurs when players are
|
||||
## too far apart from each other), `false` otherwise.
|
||||
## Only the horizontal components (x, z) are used for distance computation.
|
||||
func _is_split_state() -> bool:
|
||||
var position_difference := _get_position_difference_in_world()
|
||||
var separation_distance := _get_horizontal_length(position_difference)
|
||||
return separation_distance > max_separation
|
||||
|
||||
|
||||
func _on_size_changed():
|
||||
var screen_size = get_viewport().get_visible_rect().size
|
||||
func _on_size_changed() -> void:
|
||||
var screen_size := get_viewport().get_visible_rect().size
|
||||
|
||||
$Viewport1.size = screen_size
|
||||
$Viewport2.size = screen_size
|
||||
@@ -101,9 +101,9 @@ func _on_size_changed():
|
||||
view.material.set_shader_parameter("viewport_size", screen_size)
|
||||
|
||||
|
||||
func _compute_position_difference_in_world():
|
||||
func _get_position_difference_in_world() -> Vector3:
|
||||
return player2.position - player1.position
|
||||
|
||||
|
||||
func _compute_horizontal_length(vec):
|
||||
func _get_horizontal_length(vec: Vector3) -> float:
|
||||
return Vector2(vec.x, vec.z).length()
|
||||
|
||||
@@ -2,16 +2,16 @@ extends CharacterBody3D
|
||||
|
||||
# Moves the player
|
||||
|
||||
@export_range(1, 2) var player_id: int = 1
|
||||
@export var walk_speed: float = 2
|
||||
@export_range(1, 2) var player_id := 1
|
||||
@export var walk_speed := 2.0
|
||||
|
||||
|
||||
func _physics_process(_delta):
|
||||
var move_direction = Input.get_vector(
|
||||
"move_left_player" + str(player_id),
|
||||
"move_right_player" + str(player_id),
|
||||
"move_up_player" + str(player_id),
|
||||
"move_down_player" + str(player_id),
|
||||
func _physics_process(_delta: float) -> void:
|
||||
var move_direction := Input.get_vector(
|
||||
&"move_left_player" + str(player_id),
|
||||
&"move_right_player" + str(player_id),
|
||||
&"move_up_player" + str(player_id),
|
||||
&"move_down_player" + str(player_id),
|
||||
)
|
||||
velocity.x += move_direction.x * walk_speed
|
||||
velocity.z += move_direction.y * walk_speed
|
||||
|
||||
@@ -18,6 +18,10 @@ run/main_scene="res://split_screen.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[input]
|
||||
|
||||
move_up_player1={
|
||||
@@ -86,5 +90,4 @@ common/physics_ticks_per_second=120
|
||||
renderer/rendering_method="gl_compatibility"
|
||||
renderer/rendering_method.mobile="gl_compatibility"
|
||||
lights_and_shadows/directional_shadow/soft_shadow_filter_quality=4
|
||||
environment/defaults/default_clear_color=Color(1, 1, 1, 1)
|
||||
anti_aliasing/quality/msaa_3d=2
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=63 format=3 uid="uid://dksa68cph6y4b"]
|
||||
[gd_scene load_steps=67 format=3 uid="uid://dksa68cph6y4b"]
|
||||
|
||||
[ext_resource type="Script" path="res://camera_controller.gd" id="2"]
|
||||
[ext_resource type="Shader" path="res://split_screen.gdshader" id="3"]
|
||||
@@ -13,14 +13,12 @@ ground_horizon_color = Color(0.64625, 0.65575, 0.67075, 1)
|
||||
sky_material = SubResource("ProceduralSkyMaterial_16la2")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_vdrvu"]
|
||||
background_mode = 2
|
||||
sky = SubResource("Sky_i64ko")
|
||||
ambient_light_source = 2
|
||||
ambient_light_source = 3
|
||||
ambient_light_color = Color(0.79, 0.8775, 1, 1)
|
||||
ambient_light_sky_contribution = 0.0
|
||||
ambient_light_energy = 0.33
|
||||
reflected_light_source = 2
|
||||
tonemap_mode = 2
|
||||
glow_enabled = true
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="1"]
|
||||
shader = ExtResource("3")
|
||||
@@ -67,6 +65,24 @@ emission = Color(0.12549, 0.501961, 1, 1)
|
||||
material = SubResource("6")
|
||||
size = Vector2(200, 200)
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_3phjx"]
|
||||
offsets = PackedFloat32Array(0.139344, 0.196721, 0.237705, 0.377049, 0.598361, 0.795082, 1)
|
||||
colors = PackedColorArray(0.08, 0.432667, 1, 1, 0.945098, 1, 0.929412, 1, 0.574026, 0.479268, 0.220411, 1, 1, 0.7525, 0.45, 1, 0.0322, 0.23, 0.0322, 1, 0.181569, 0.353991, 0.245845, 1, 1, 1, 1, 1)
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_2bwlb"]
|
||||
noise_type = 4
|
||||
domain_warp_enabled = true
|
||||
domain_warp_frequency = 0.002
|
||||
|
||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_ha3y6"]
|
||||
seamless = true
|
||||
color_ramp = SubResource("Gradient_3phjx")
|
||||
noise = SubResource("FastNoiseLite_2bwlb")
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_i0wmt"]
|
||||
albedo_texture = SubResource("NoiseTexture2D_ha3y6")
|
||||
uv1_scale = Vector3(64, 64, 64)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="8"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="9"]
|
||||
@@ -265,6 +281,17 @@ surface_material_override/0 = SubResource("StandardMaterial3D_63nwq")
|
||||
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="Player1"]
|
||||
light_color = Color(1, 0, 0, 1)
|
||||
light_energy = 2.5
|
||||
omni_range = 10.0
|
||||
|
||||
[node name="Label3D" type="Label3D" parent="Player1"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
pixel_size = 0.01
|
||||
offset = Vector2(0, 50)
|
||||
billboard = 1
|
||||
double_sided = false
|
||||
modulate = Color(1, 0.323333, 0.3, 1)
|
||||
text = "P1"
|
||||
|
||||
[node name="Player2" type="CharacterBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.184, 0.875, 3.019)
|
||||
@@ -286,12 +313,24 @@ surface_material_override/0 = SubResource("StandardMaterial3D_wi7e2")
|
||||
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="Player2"]
|
||||
light_color = Color(0.12549, 0.501961, 1, 1)
|
||||
light_energy = 2.5
|
||||
omni_range = 10.0
|
||||
|
||||
[node name="Label3D" type="Label3D" parent="Player2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
pixel_size = 0.01
|
||||
offset = Vector2(0, 50)
|
||||
billboard = 1
|
||||
double_sided = false
|
||||
modulate = Color(0.3, 0.65, 1, 1)
|
||||
text = "P2"
|
||||
|
||||
[node name="Ground" type="StaticBody3D" parent="."]
|
||||
|
||||
[node name="Mesh" type="MeshInstance3D" parent="Ground"]
|
||||
transform = Transform3D(20, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0)
|
||||
mesh = SubResource("7")
|
||||
surface_material_override/0 = SubResource("StandardMaterial3D_i0wmt")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground"]
|
||||
transform = Transform3D(200, 0, 0, 0, 1, 0, 0, 0, 200, 0, -1, 0)
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
@tool
|
||||
extends Node3D
|
||||
## Sets a random color to all objects in the "walls" group.
|
||||
## To use, attach this script to the "Walls" node.
|
||||
|
||||
# Set a random color to all objects in the "walls" group.
|
||||
# To use, attach this script to the "Walls" node.
|
||||
|
||||
func _ready():
|
||||
var walls = get_tree().get_nodes_in_group("walls")
|
||||
func _ready() -> void:
|
||||
var walls := get_tree().get_nodes_in_group("walls")
|
||||
for wall in walls:
|
||||
var material = StandardMaterial3D.new()
|
||||
var material := StandardMaterial3D.new()
|
||||
material.albedo_color = Color(randf(), randf(), randf())
|
||||
|
||||
wall.material_override = material
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
extends Node3D
|
||||
|
||||
# Used for checking if the mouse is inside the Area3D.
|
||||
var is_mouse_inside = false
|
||||
# The last processed input touch/mouse event. To calculate relative movement.
|
||||
var last_event_pos2D = null
|
||||
# The time of the last event in seconds since engine start.
|
||||
var last_event_time: float = -1.0
|
||||
## Used for checking if the mouse is inside the Area3D.
|
||||
var is_mouse_inside := false
|
||||
|
||||
@onready var node_viewport = $SubViewport
|
||||
@onready var node_quad = $Quad
|
||||
@onready var node_area = $Quad/Area3D
|
||||
## The last processed input touch/mouse event. Used to calculate relative movement.
|
||||
var last_event_pos2D := Vector2()
|
||||
|
||||
func _ready():
|
||||
## The time of the last event in seconds since engine start.
|
||||
var last_event_time := -1.0
|
||||
|
||||
@onready var node_viewport: SubViewport = $SubViewport
|
||||
@onready var node_quad: MeshInstance3D = $Quad
|
||||
@onready var node_area: Area3D = $Quad/Area3D
|
||||
|
||||
func _ready() -> void:
|
||||
node_area.mouse_entered.connect(_mouse_entered_area)
|
||||
node_area.mouse_exited.connect(_mouse_exited_area)
|
||||
node_area.input_event.connect(_mouse_input_event)
|
||||
@@ -21,20 +23,20 @@ func _ready():
|
||||
set_process(false)
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
func _process(_delta: float) -> void:
|
||||
# NOTE: Remove this function if you don't plan on using billboard settings.
|
||||
rotate_area_to_billboard()
|
||||
|
||||
|
||||
func _mouse_entered_area():
|
||||
func _mouse_entered_area() -> void:
|
||||
is_mouse_inside = true
|
||||
|
||||
|
||||
func _mouse_exited_area():
|
||||
func _mouse_exited_area() -> void:
|
||||
is_mouse_inside = false
|
||||
|
||||
|
||||
func _unhandled_input(event):
|
||||
func _unhandled_input(event: InputEvent) -> void:
|
||||
# Check if the event is a non-mouse/non-touch event
|
||||
for mouse_event in [InputEventMouseButton, InputEventMouseMotion, InputEventScreenDrag, InputEventScreenTouch]:
|
||||
if is_instance_of(event, mouse_event):
|
||||
@@ -44,23 +46,23 @@ func _unhandled_input(event):
|
||||
node_viewport.push_input(event)
|
||||
|
||||
|
||||
func _mouse_input_event(_camera: Camera3D, event: InputEvent, event_position: Vector3, _normal: Vector3, _shape_idx: int):
|
||||
# Get mesh size to detect edges and make conversions. This code only support PlaneMesh and QuadMesh.
|
||||
var quad_mesh_size = node_quad.mesh.size
|
||||
func _mouse_input_event(_camera: Camera3D, event: InputEvent, event_position: Vector3, _normal: Vector3, _shape_idx: int) -> void:
|
||||
# Get mesh size to detect edges and make conversions. This code only supports PlaneMesh and QuadMesh.
|
||||
var quad_mesh_size: Vector2 = node_quad.mesh.size
|
||||
|
||||
# Event position in Area3D in world coordinate space.
|
||||
var event_pos3D = event_position
|
||||
var event_pos3D := event_position
|
||||
|
||||
# Current time in seconds since engine start.
|
||||
var now: float = Time.get_ticks_msec() / 1000.0
|
||||
var now := Time.get_ticks_msec() / 1000.0
|
||||
|
||||
# Convert position to a coordinate space relative to the Area3D node.
|
||||
# NOTE: affine_inverse accounts for the Area3D node's scale, rotation, and position in the scene!
|
||||
# NOTE: `affine_inverse()` accounts for the Area3D node's scale, rotation, and position in the scene!
|
||||
event_pos3D = node_quad.global_transform.affine_inverse() * event_pos3D
|
||||
|
||||
# TODO: Adapt to bilboard mode or avoid completely.
|
||||
|
||||
var event_pos2D: Vector2 = Vector2()
|
||||
var event_pos2D := Vector2()
|
||||
|
||||
if is_mouse_inside:
|
||||
# Convert the relative event position from 3D to 2D.
|
||||
@@ -109,15 +111,15 @@ func _mouse_input_event(_camera: Camera3D, event: InputEvent, event_position: Ve
|
||||
node_viewport.push_input(event)
|
||||
|
||||
|
||||
func rotate_area_to_billboard():
|
||||
var billboard_mode = node_quad.get_surface_override_material(0).billboard_mode
|
||||
func rotate_area_to_billboard() -> void:
|
||||
var billboard_mode: BaseMaterial3D.BillboardMode = node_quad.get_surface_override_material(0).billboard_mode
|
||||
|
||||
# Try to match the area with the material's billboard setting, if enabled.
|
||||
if billboard_mode > 0:
|
||||
# Get the camera.
|
||||
var camera = get_viewport().get_camera_3d()
|
||||
var camera := get_viewport().get_camera_3d()
|
||||
# Look in the same direction as the camera.
|
||||
var look = camera.to_global(Vector3(0, 0, -100)) - camera.global_transform.origin
|
||||
var look := camera.to_global(Vector3(0, 0, -100)) - camera.global_transform.origin
|
||||
look = node_area.position + look
|
||||
|
||||
# Y-Billboard: Lock Y rotation, but gives bad results if the camera is tilted.
|
||||
|
||||
@@ -18,6 +18,10 @@ run/main_scene="res://gui_in_3d.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[gui]
|
||||
|
||||
theme/default_theme_scale=2.0
|
||||
|
||||
@@ -17,6 +17,10 @@ run/main_scene="res://screen_capture.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
extends Node
|
||||
|
||||
@onready var captured_image = $CapturedImage
|
||||
@onready var captured_image: TextureRect = $CapturedImage
|
||||
@onready var capture_button: Button = $CaptureButton
|
||||
|
||||
func _on_CaptureButton_pressed():
|
||||
|
||||
func _ready() -> void:
|
||||
# Focus button for keyboard/gamepad-friendly navigation.
|
||||
capture_button.grab_focus()
|
||||
|
||||
|
||||
func _on_capture_button_pressed() -> void:
|
||||
# Retrieve the captured image.
|
||||
var img = get_viewport().get_texture().get_image()
|
||||
var img := get_viewport().get_texture().get_image()
|
||||
|
||||
# Create a texture for it.
|
||||
var tex = ImageTexture.create_from_image(img)
|
||||
var tex := ImageTexture.create_from_image(img)
|
||||
|
||||
# Set the texture to the captured image node.
|
||||
captured_image.set_texture(tex)
|
||||
|
||||
# Colorize the button with a random color, so you can see which button belongs to which capture.
|
||||
capture_button.modulate = Color.from_hsv(randf(), randf_range(0.2, 0.8), 1.0)
|
||||
|
||||
@@ -41,6 +41,7 @@ offset_left = 50.0
|
||||
offset_top = 50.0
|
||||
offset_right = 190.0
|
||||
offset_bottom = 110.0
|
||||
text = "Capture screen"
|
||||
text = "Capture
|
||||
Screen"
|
||||
|
||||
[connection signal="pressed" from="CaptureButton" to="." method="_on_CaptureButton_pressed"]
|
||||
[connection signal="pressed" from="CaptureButton" to="." method="_on_capture_button_pressed"]
|
||||
|
||||
Reference in New Issue
Block a user