feat: Add initial player scene with character models and effects, implement core lobby UI and functionality, and introduce a 3D outline shader.

This commit is contained in:
Yogi Wiguna
2026-03-26 12:12:08 +08:00
parent 7b1f884e84
commit ebc1c9868a
4 changed files with 64 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
shader_type spatial;
render_mode cull_front, unshaded;
// Controls the width of the outline
uniform float outline_thickness : hint_range(0.0, 0.5) = 0.03;
// Controls the color of the outline
uniform vec4 outline_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
void vertex() {
// The core of the inverted hull method:
// We push the vertices outward along their normal vectors.
// Since front faces are culled, this creates the outline border.
VERTEX += NORMAL * outline_thickness;
}
void fragment() {
// Apply the solid outline color
ALBEDO = outline_color.rgb;
ALPHA = outline_color.a;
}
+1
View File
@@ -0,0 +1 @@
uid://cc6tnqkwd8iy6
+22
View File
@@ -145,6 +145,10 @@ func _ready():
refresh_btn.pressed.connect(_on_refresh_pressed)
join_btn.pressed.connect(_on_join_pressed)
back_btn.pressed.connect(_on_back_pressed)
if room_list:
room_list.item_selected.connect(_on_room_selected)
room_list.item_activated.connect(_on_room_activated)
if room_list_profile_btn:
room_list_profile_btn.pressed.connect(_on_profile_btn_pressed)
@@ -361,6 +365,24 @@ func _on_refresh_pressed() -> void:
room_list.clear()
LobbyManager.refresh_room_list()
func _on_room_selected(index: int) -> void:
"""Automatically fill the match_id input when a room is clicked so it's not lost on focus change."""
if index < LobbyManager.available_rooms.size():
var room = LobbyManager.available_rooms[index]
if LobbyManager.is_lan_mode:
var ip = room.get("ip", "")
if not ip.is_empty():
match_id_input.text = ip
else:
var mid = room.get("match_id", "")
if not mid.is_empty():
match_id_input.text = mid
func _on_room_activated(index: int) -> void:
"""Handle double-clicking a room to join immediately."""
_on_room_selected(index)
_on_join_pressed()
func _on_join_pressed() -> void:
var match_id = match_id_input.text.strip_edges()
+20
View File
@@ -438,6 +438,26 @@ func set_character(character_name: String) -> void:
anim_player.root_node = anim_player.get_path_to(active_character)
# Start with idle animation
play_idle_animation()
# Apply outline shader to the active character
if active_character:
_apply_outline_recursive(active_character)
func _apply_outline_recursive(node: Node):
if node is MeshInstance3D and node.mesh:
for i in range(node.mesh.get_surface_count()):
var mat = node.get_active_material(i)
if mat:
# Only apply if it doesn't already have a next pass
if not mat.next_pass:
var unique_mat = mat.duplicate()
var outline_mat = ShaderMaterial.new()
outline_mat.shader = load("res://assets/shaders/outline3d.gdshader")
unique_mat.next_pass = outline_mat
node.set_surface_override_material(i, unique_mat)
for child in node.get_children():
_apply_outline_recursive(child)
@rpc("any_peer", "call_local", "reliable")
func sync_character(character_name: String) -> void: