feat: Introduce tekton_walking 3D model, implement a CameraContextManager for dynamic camera positioning, and add a ScreenShakeManager script.
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,42 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="scene"
|
||||||
|
importer_version=1
|
||||||
|
type="PackedScene"
|
||||||
|
uid="uid://bye8rbeqmxy1m"
|
||||||
|
path="res://.godot/imported/tekton_walking.glb-4042e6c5856f09fa2cc375563a11f70d.scn"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/models/meshes/tekton/tekton_walking.glb"
|
||||||
|
dest_files=["res://.godot/imported/tekton_walking.glb-4042e6c5856f09fa2cc375563a11f70d.scn"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
nodes/root_type=""
|
||||||
|
nodes/root_name=""
|
||||||
|
nodes/root_script=null
|
||||||
|
nodes/apply_root_scale=true
|
||||||
|
nodes/root_scale=1.0
|
||||||
|
nodes/import_as_skeleton_bones=false
|
||||||
|
nodes/use_name_suffixes=true
|
||||||
|
nodes/use_node_type_suffixes=true
|
||||||
|
meshes/ensure_tangents=true
|
||||||
|
meshes/generate_lods=true
|
||||||
|
meshes/create_shadow_meshes=true
|
||||||
|
meshes/light_baking=1
|
||||||
|
meshes/lightmap_texel_size=0.2
|
||||||
|
meshes/force_disable_compression=false
|
||||||
|
skins/use_named_skins=true
|
||||||
|
animation/import=true
|
||||||
|
animation/fps=30
|
||||||
|
animation/trimming=false
|
||||||
|
animation/remove_immutable_tracks=true
|
||||||
|
animation/import_rest_as_RESET=false
|
||||||
|
import_script/path=""
|
||||||
|
materials/extract=0
|
||||||
|
materials/extract_format=0
|
||||||
|
materials/extract_path=""
|
||||||
|
_subresources={}
|
||||||
|
gltf/naming_version=2
|
||||||
|
gltf/embedded_image_handling=1
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 169 KiB |
@@ -0,0 +1,44 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://bskihcaeo1smd"
|
||||||
|
path.s3tc="res://.godot/imported/tekton_walking_GOGGLE 2 UV Tex2.png-73ef37400d33fb36d94c2bd4fd46bef6.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
generator_parameters={
|
||||||
|
"md5": "54c5e1acb27020ed20da0689345f47ec"
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/models/meshes/tekton/tekton_walking_GOGGLE 2 UV Tex2.png"
|
||||||
|
dest_files=["res://.godot/imported/tekton_walking_GOGGLE 2 UV Tex2.png-73ef37400d33fb36d94c2bd4fd46bef6.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 557 KiB |
@@ -0,0 +1,44 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://byepwsmeulscp"
|
||||||
|
path.s3tc="res://.godot/imported/tekton_walking_WhiteFluffyTowel_normal.jpg-7319bdbeda72417bd0eb9d7bd590fcea.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
generator_parameters={
|
||||||
|
"md5": "286009441fbbc5f913f0d3b39741d839"
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/models/meshes/tekton/tekton_walking_WhiteFluffyTowel_normal.jpg"
|
||||||
|
dest_files=["res://.godot/imported/tekton_walking_WhiteFluffyTowel_normal.jpg-7319bdbeda72417bd0eb9d7bd590fcea.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=1
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=1
|
||||||
|
roughness/src_normal="res://assets/models/meshes/tekton/tekton_walking_WhiteFluffyTowel_normal.jpg"
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 945 KiB |
@@ -0,0 +1,44 @@
|
|||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://ctompad3g7pc3"
|
||||||
|
path.s3tc="res://.godot/imported/tekton_walking_WhiteFluffyTowel_roughness.png-5ce3697bfe5ea29c1ef189f5d2cf4a98.s3tc.ctex"
|
||||||
|
metadata={
|
||||||
|
"imported_formats": ["s3tc_bptc"],
|
||||||
|
"vram_texture": true
|
||||||
|
}
|
||||||
|
generator_parameters={
|
||||||
|
"md5": "3650b521fc7995add9cc4eb21b0b803a"
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://assets/models/meshes/tekton/tekton_walking_WhiteFluffyTowel_roughness.png"
|
||||||
|
dest_files=["res://.godot/imported/tekton_walking_WhiteFluffyTowel_roughness.png-5ce3697bfe5ea29c1ef189f5d2cf4a98.s3tc.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=2
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/uastc_level=0
|
||||||
|
compress/rdo_quality_loss=0.0
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=true
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/channel_remap/red=0
|
||||||
|
process/channel_remap/green=1
|
||||||
|
process/channel_remap/blue=2
|
||||||
|
process/channel_remap/alpha=3
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=0
|
||||||
+14
-2
@@ -9,6 +9,7 @@ var ui_manager
|
|||||||
var goals_cycle_manager
|
var goals_cycle_manager
|
||||||
var screen_shake_manager
|
var screen_shake_manager
|
||||||
var touch_controls
|
var touch_controls
|
||||||
|
var camera_context_manager
|
||||||
|
|
||||||
# Minimal local state
|
# Minimal local state
|
||||||
var _connection_check_timer: float = 0.0
|
var _connection_check_timer: float = 0.0
|
||||||
@@ -76,9 +77,8 @@ func _init_managers():
|
|||||||
screen_shake_manager = load("res://scripts/managers/screen_shake.gd").new()
|
screen_shake_manager = load("res://scripts/managers/screen_shake.gd").new()
|
||||||
screen_shake_manager.name = "ScreenShakeManager"
|
screen_shake_manager.name = "ScreenShakeManager"
|
||||||
add_child(screen_shake_manager)
|
add_child(screen_shake_manager)
|
||||||
screen_shake_manager.initialize($Camera3D)
|
screen_shake_manager.initialize($Camera3D200)
|
||||||
|
|
||||||
# Touch controls for mobile
|
|
||||||
# Touch controls for mobile
|
# Touch controls for mobile
|
||||||
touch_controls = get_node_or_null("TouchControls")
|
touch_controls = get_node_or_null("TouchControls")
|
||||||
if not touch_controls:
|
if not touch_controls:
|
||||||
@@ -89,6 +89,12 @@ func _init_managers():
|
|||||||
|
|
||||||
touch_controls.initialize(self)
|
touch_controls.initialize(self)
|
||||||
|
|
||||||
|
# NEW: Camera Context Manager for dynamic camera position
|
||||||
|
camera_context_manager = load("res://scripts/managers/camera_context_manager.gd").new()
|
||||||
|
camera_context_manager.name = "CameraContextManager"
|
||||||
|
add_child(camera_context_manager)
|
||||||
|
camera_context_manager.initialize($Camera3D200, screen_shake_manager)
|
||||||
|
|
||||||
# Connect signals for UI updates
|
# Connect signals for UI updates
|
||||||
goals_cycle_manager.timer_updated.connect(_on_timer_updated)
|
goals_cycle_manager.timer_updated.connect(_on_timer_updated)
|
||||||
goals_cycle_manager.score_updated.connect(_on_score_updated)
|
goals_cycle_manager.score_updated.connect(_on_score_updated)
|
||||||
@@ -324,6 +330,8 @@ func _setup_host_game():
|
|||||||
ui_manager.set_local_player(player_character)
|
ui_manager.set_local_player(player_character)
|
||||||
if touch_controls:
|
if touch_controls:
|
||||||
touch_controls.set_player(player_character)
|
touch_controls.set_player(player_character)
|
||||||
|
if camera_context_manager:
|
||||||
|
camera_context_manager.set_player(player_character)
|
||||||
|
|
||||||
# Set host name
|
# Set host name
|
||||||
player_character.display_name = LobbyManager.local_player_name
|
player_character.display_name = LobbyManager.local_player_name
|
||||||
@@ -436,6 +444,8 @@ func _setup_client_game():
|
|||||||
ui_manager.set_local_player(player_character)
|
ui_manager.set_local_player(player_character)
|
||||||
if touch_controls:
|
if touch_controls:
|
||||||
touch_controls.set_player(player_character)
|
touch_controls.set_player(player_character)
|
||||||
|
if camera_context_manager:
|
||||||
|
camera_context_manager.set_player(player_character)
|
||||||
ui_manager.update_button_states()
|
ui_manager.update_button_states()
|
||||||
print("Client: Configured local player ", my_id)
|
print("Client: Configured local player ", my_id)
|
||||||
|
|
||||||
@@ -654,6 +664,8 @@ func add_player_character(peer_id: int, is_bot: bool = false):
|
|||||||
ui_manager.set_local_player(player_character)
|
ui_manager.set_local_player(player_character)
|
||||||
if touch_controls:
|
if touch_controls:
|
||||||
touch_controls.set_player(player_character)
|
touch_controls.set_player(player_character)
|
||||||
|
if camera_context_manager:
|
||||||
|
camera_context_manager.set_player(player_character)
|
||||||
ui_manager.update_button_states()
|
ui_manager.update_button_states()
|
||||||
ui_manager.update_playerboard_ui()
|
ui_manager.update_playerboard_ui()
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -106,10 +106,10 @@ current = true
|
|||||||
fov = 35.5
|
fov = 35.5
|
||||||
|
|
||||||
[node name="Camera3D200" type="Camera3D" parent="." unique_id=1763366951]
|
[node name="Camera3D200" type="Camera3D" parent="." unique_id=1763366951]
|
||||||
transform = Transform3D(1, 0, 0, 0, 0.5077037, 0.86153173, 0, -0.86153173, 0.5077037, 7, 19.635756, 19.007332)
|
transform = Transform3D(1, 0, 0, 0, 0.5077037, 0.86153173, 0, -0.86153173, 0.5077037, 7, 19.636, 22.5)
|
||||||
environment = ExtResource("4_ky38j")
|
environment = ExtResource("4_ky38j")
|
||||||
current = true
|
current = true
|
||||||
fov = 35.5
|
fov = 21.0
|
||||||
size = 15.0
|
size = 15.0
|
||||||
|
|
||||||
[node name="PlayerboardPanel" type="PanelContainer" parent="." unique_id=1098203639]
|
[node name="PlayerboardPanel" type="PanelContainer" parent="." unique_id=1098203639]
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
# CameraContextManager
|
||||||
|
# Handles camera position based on player's row on the board.
|
||||||
|
|
||||||
|
# var screen_shake_manager: Node # Removed
|
||||||
|
var camera: Camera3D
|
||||||
|
var player: Node3D
|
||||||
|
|
||||||
|
# Configuration Map: Row Threshold -> Target Position
|
||||||
|
# We use a list of dictionaries to define ranges.
|
||||||
|
# Setup A: Rows 0-5
|
||||||
|
# Setup B: Rows 6-9
|
||||||
|
# Setup C: Rows 10+
|
||||||
|
var camera_setups = [
|
||||||
|
{ "max_row": 5, "position": Vector3(7.0, 19.636, 15.0) },
|
||||||
|
{ "max_row": 9, "position": Vector3(7.0, 19.636, 19.0) },
|
||||||
|
{ "max_row": 999, "position": Vector3(7.0, 19.22636, 22.5) } # Default/Bottom
|
||||||
|
]
|
||||||
|
|
||||||
|
var unique_id: int
|
||||||
|
|
||||||
|
func initialize(p_camera: Camera3D, _p_shake_manager: Node):
|
||||||
|
camera = p_camera
|
||||||
|
# screen_shake_manager = p_shake_manager
|
||||||
|
print("[CameraContextManager] Initialized with camera")
|
||||||
|
|
||||||
|
func set_player(p_player: Node3D):
|
||||||
|
player = p_player
|
||||||
|
unique_id = p_player.name.to_int()
|
||||||
|
# Try to get movement manager (might be initializing)
|
||||||
|
var movement_mgr = player.get("movement_manager")
|
||||||
|
|
||||||
|
if not movement_mgr and player.get("movement_manager") == null:
|
||||||
|
# Try direct access if script variable
|
||||||
|
movement_mgr = player.movement_manager
|
||||||
|
|
||||||
|
if movement_mgr:
|
||||||
|
if not movement_mgr.movement_finished.is_connected(_on_player_moved):
|
||||||
|
movement_mgr.movement_finished.connect(_on_player_moved)
|
||||||
|
else:
|
||||||
|
print("[CameraContextManager] Warning: movement_manager not found on player. Retrying in 0.5s...")
|
||||||
|
await get_tree().create_timer(0.5).timeout
|
||||||
|
if player == p_player: # Ensure player hasn't changed
|
||||||
|
set_player(p_player) # Retry
|
||||||
|
_update_camera_target()
|
||||||
|
|
||||||
|
func _on_player_moved():
|
||||||
|
# print("[CameraContextManager] Player moved signal received")
|
||||||
|
_update_camera_target()
|
||||||
|
|
||||||
|
func _update_camera_target():
|
||||||
|
if not player or not camera:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Get player row (Z coordinate in 3D world / Y in GridMap)
|
||||||
|
# In this game: Grid Y maps to World Z.
|
||||||
|
# Player current_position is Vector2i(grid_x, grid_y)
|
||||||
|
|
||||||
|
var current_row = player.current_position.y
|
||||||
|
var target_pos = Vector3.ZERO
|
||||||
|
|
||||||
|
for i in range(camera_setups.size()):
|
||||||
|
var setup = camera_setups[i]
|
||||||
|
if current_row <= setup.max_row:
|
||||||
|
target_pos = setup.position
|
||||||
|
break
|
||||||
|
|
||||||
|
# print("[CameraContextManager] Player Row: %d -> Selected Setup: %d (Target: %s)" % [current_row, setup_index, target_pos])
|
||||||
|
|
||||||
|
# Update ScreenShakeManager's target
|
||||||
|
# Update Camera Position directly with Tween
|
||||||
|
if camera.position != target_pos:
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.tween_property(camera, "position", target_pos, 1.0).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://btvpagdk2gwhg
|
||||||
@@ -6,7 +6,7 @@ var camera: Camera3D
|
|||||||
var shake_intensity: float = 0.0
|
var shake_intensity: float = 0.0
|
||||||
var shake_duration: float = 0.0
|
var shake_duration: float = 0.0
|
||||||
var shake_timer: float = 0.0
|
var shake_timer: float = 0.0
|
||||||
var original_position: Vector3
|
var target_position: Vector3 # Replaces original_position
|
||||||
|
|
||||||
# Shake presets
|
# Shake presets
|
||||||
const SHAKE_TARGETED: Dictionary = {"intensity": 0.15, "duration": 0.4}
|
const SHAKE_TARGETED: Dictionary = {"intensity": 0.15, "duration": 0.4}
|
||||||
@@ -17,56 +17,17 @@ func initialize(p_camera: Camera3D):
|
|||||||
"""Initialize with specific camera instance."""
|
"""Initialize with specific camera instance."""
|
||||||
camera = p_camera
|
camera = p_camera
|
||||||
if camera:
|
if camera:
|
||||||
original_position = camera.position
|
target_position = camera.position
|
||||||
print("[ScreenShakeManager] Initialized with camera: ", camera.name)
|
print("[ScreenShakeManager] Initialized with camera: ", camera.name)
|
||||||
else:
|
else:
|
||||||
push_warning("[ScreenShakeManager] Initialized with null camera")
|
push_warning("[ScreenShakeManager] Initialized with null camera")
|
||||||
|
|
||||||
func _process(delta):
|
func set_target_position(new_pos: Vector3, duration: float = 1.0):
|
||||||
if shake_timer > 0:
|
"""Smoothly transition to a new base camera position."""
|
||||||
shake_timer -= delta
|
if target_position == new_pos:
|
||||||
if camera:
|
|
||||||
var shake_offset = Vector3(
|
|
||||||
randf_range(-shake_intensity, shake_intensity),
|
|
||||||
randf_range(-shake_intensity, shake_intensity),
|
|
||||||
randf_range(-shake_intensity * 0.5, shake_intensity * 0.5)
|
|
||||||
)
|
|
||||||
camera.position = original_position + shake_offset
|
|
||||||
|
|
||||||
if shake_timer <= 0:
|
|
||||||
_reset_camera()
|
|
||||||
|
|
||||||
func _reset_camera():
|
|
||||||
if camera:
|
|
||||||
camera.position = original_position
|
|
||||||
shake_timer = 0.0
|
|
||||||
shake_intensity = 0.0
|
|
||||||
|
|
||||||
func shake(intensity: float, duration: float):
|
|
||||||
"""Trigger camera shake with given intensity and duration."""
|
|
||||||
if not camera:
|
|
||||||
push_warning("Screen shake requested but no camera assigned!")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if camera:
|
# Tween the target position
|
||||||
# If already shaking, reset camera first to get true original position
|
var tween = create_tween()
|
||||||
if shake_timer > 0:
|
tween.tween_property(self, "target_position", new_pos, duration).set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
|
||||||
camera.position = original_position
|
|
||||||
else:
|
|
||||||
original_position = camera.position
|
|
||||||
|
|
||||||
shake_intensity = intensity
|
|
||||||
shake_duration = duration
|
|
||||||
shake_timer = duration
|
|
||||||
|
|
||||||
func shake_targeted():
|
|
||||||
"""Called when local player is targeted by opponent's powerup."""
|
|
||||||
shake(SHAKE_TARGETED.intensity, SHAKE_TARGETED.duration)
|
|
||||||
|
|
||||||
func shake_goal_complete():
|
|
||||||
"""Called when local player completes a goal."""
|
|
||||||
shake(SHAKE_GOAL_COMPLETE.intensity, SHAKE_GOAL_COMPLETE.duration)
|
|
||||||
|
|
||||||
func shake_light():
|
|
||||||
"""Light shake for minor events."""
|
|
||||||
shake(SHAKE_LIGHT.intensity, SHAKE_LIGHT.duration)
|
|
||||||
|
|||||||
Reference in New Issue
Block a user