Compare commits

...

2 commits

Author SHA1 Message Date
TheThomaas 3f8c100f17 Update Camera and add RunState 2026-09-23 17:56:57 +02:00
TheThomaas f19cb0e796 Start work on camera lock 2026-09-23 17:17:19 +02:00
15 changed files with 428 additions and 24 deletions

View file

@ -20,6 +20,16 @@ var active : bool = true : set = set_active
var cam_aimed : bool = false #if true, cam goes into "aim/shooter mode", above the play char shoulder
@export var aim_cam_pos : Vector3 = Vector3(1.4, 0.9, 0.0)
var aim_cam_pos_side : bool = true #false = left, true = right
@export var aim_cam_transition_speed : float = 10.0
var cam_offset : Vector3 = Vector3.ZERO #decalage actuel de la camera (interpole)
@export_range(0.1, 1.0, 0.01) var aim_distance_multiplier : float = 0.6 #1.0 = meme distance que hors visee, 0.5 = moitie moins loin
@export var min_cam_distance : float = 0.8 #distance minimale entre le pivot et la camera
var cam_distance_mult : float = 1.0 #multiplicateur actuel (interpole)
@export_group("Lock-on variables")
@export var lock_on_speed : float = 8.0
var lock_target : Node3D = null
#keybinding variables
var aim_cam_action : StringName
@ -49,8 +59,14 @@ func set_active(state : bool) -> void:
func _input(event: InputEvent) -> void:
#change cam mode (default, aim)
if event.is_action_pressed(aim_cam_action):
cam_aimed = !cam_aimed
#if event.is_action_pressed(aim_cam_action):
#cam_aimed = !cam_aimed
if event is InputEventMouseMotion:
if has_lock_target(): return
var viewport_transform: Transform2D = get_tree().root.get_final_transform()
var mouse_motion = event.xformed_by(viewport_transform).relative
rotate_from_vector(mouse_motion * mouse_sensibility)
if event is InputEventMouseMotion:
var viewport_transform: Transform2D = get_tree().root.get_final_transform()
@ -59,11 +75,25 @@ func _input(event: InputEvent) -> void:
func _process(delta: float) -> void:
#position the cam according to its mode (default, aim (with left or right side))
if !cam_aimed: cam.position = Vector3(0.0, 0.0, spring_arm.get_hit_length())
else: cam.position = Vector3(aim_cam_pos.x, aim_cam_pos.y, spring_arm.get_hit_length())
var target_offset : Vector3 = Vector3.ZERO
var target_mult : float = 1.0
if cam_aimed:
var side : float = 1.0 if aim_cam_pos_side else -1.0 #true = droite, false = gauche
target_offset = Vector3(aim_cam_pos.x * side, aim_cam_pos.y, aim_cam_pos.z)
target_mult = aim_distance_multiplier
var camera_motion = Input.get_vector(cam_look_left_action, cam_look_right_action, cam_look_up_action, cam_look_down_action)
rotate_from_vector(camera_motion * joystick_sensibility)
var weight : float = clampf(aim_cam_transition_speed * delta, 0.0, 1.0)
cam_offset = cam_offset.lerp(target_offset, weight)
cam_distance_mult = lerpf(cam_distance_mult, target_mult, weight)
var distance : float = maxf(spring_arm.get_hit_length() * cam_distance_mult + cam_offset.z, min_cam_distance)
cam.position = Vector3(cam_offset.x, cam_offset.y, distance)
if has_lock_target():
lock_on_handling(delta)
else:
var camera_motion = Input.get_vector(cam_look_left_action, cam_look_right_action, cam_look_up_action, cam_look_down_action)
rotate_from_vector(camera_motion * joystick_sensibility)
#handle zoom
zoom_handling(delta)
@ -81,3 +111,24 @@ func zoom_handling(delta : float) -> void:
spring_arm.spring_length += Input.get_axis(cam_zoom_in_action, cam_zoom_out_action) * zoom_speed * delta
spring_arm.spring_length = clamp(spring_arm.spring_length, min_spring_length, max_spring_length)
func switch_aim_side() -> void:
aim_cam_pos_side = !aim_cam_pos_side
func has_lock_target() -> bool:
return is_instance_valid(lock_target)
func lock_on_handling(delta : float) -> void:
#tourne progressivement la camera vers la cible verrouillee
var to_target : Vector3 = lock_target.global_position - global_position
var flat_dist : float = Vector2(to_target.x, to_target.z).length()
if flat_dist < 0.01: return
var target_yaw : float = atan2(-to_target.x, -to_target.z)
var target_pitch : float = clampf(atan2(to_target.y, flat_dist), deg_to_rad(min_limit_x), deg_to_rad(max_limit_x))
var weight : float = clampf(lock_on_speed * delta, 0.0, 1.0)
rotation.y = lerp_angle(rotation.y, target_yaw, weight)
rotation.x = lerp_angle(rotation.x, target_pitch, weight)
func set_lock_target(t : Node3D) -> void:
lock_target = t

View file

@ -36,6 +36,7 @@ func attribute_keybinds() -> void:
play_char_ref.move_right_action = move_right_action
play_char_ref.run_action = run_action
play_char_ref.jump_action = jump_action
play_char_ref.aim_cam_action = aim_cam_action
cam_holder_ref.aim_cam_action = aim_cam_action
cam_holder_ref.cam_zoom_in_action = cam_zoom_in_action

View file

@ -7,6 +7,7 @@
[ext_resource type="Script" uid="uid://bf6hjwfa74ttj" path="res://game/player/StateMachine/IdleState.gd" id="4_38lxl"]
[ext_resource type="Script" uid="uid://2agliol5dulc" path="res://game/player/StateMachine/WalkState.gd" id="4_lg056"]
[ext_resource type="Script" uid="uid://dr5p8ygj25w6x" path="res://game/player/StateMachine/JumpState.gd" id="6_lwgph"]
[ext_resource type="Script" uid="uid://dn5idrvu68k83" path="res://game/player/StateMachine/AimState.gd" id="7_kxr4l"]
[sub_resource type="Curve" id="Curve_kxr4l"]
_limits = [0.0, 10.0, 0.0, 1.0]
@ -77,5 +78,10 @@ script = ExtResource("4_lg056")
[node name="JumpState" type="Node" parent="StateMachine" unique_id=711160985]
script = ExtResource("6_lwgph")
[node name="AimState" type="Node" parent="StateMachine" unique_id=296560188]
script = ExtResource("7_kxr4l")
[node name="RunState" type="Node" parent="StateMachine" unique_id=1345421775]
[node name="InputManagementComponent" type="Node" parent="." unique_id=1981951371]
script = ExtResource("2_r5dqo")

View file

@ -0,0 +1,159 @@
extends State
class_name AimState
var state_name : String = "Aim"
var play_char : CharacterBody3D
@export var aim_action : StringName = &"player_aim_camera"
@export var switch_target_action : StringName = &"player_aim_switch_target"
@export var unlock_action : StringName = &"player_aim_unlock"
@export_group("Targeting")
@export var throw_range : float = 20.0
@export var max_aim_angle : float = 35.0 #angle max (deg) entre l'axe camera et une cible pour qu'elle soit candidate
@export var auto_lock_angle : float = 12.0 #si une cible passe sous cet angle, on se verrouille dessus
@export var lose_range_margin : float = 1.25 #marge de distance avant de perdre une cible deja verrouillee
@export var check_line_of_sight : bool = true
@export_flags_3d_physics var line_of_sight_mask : int = 1
@export_group("Movement")
@export var aim_move_speed : float = 3.0
@export var aim_move_accel : float = 8.0
var auto_lock_blocked : bool = false #true apres un deverrouillage manuel, tant que la cible est encore au centre
func enter(play_char_ref : CharacterBody3D) -> void:
play_char = play_char_ref
auto_lock_blocked = false
verifications()
func verifications() -> void:
play_char.floor_snap_length = 1.0
play_char.cam_holder.cam_aimed = true
func exit() -> void:
release_target()
if play_char: play_char.cam_holder.cam_aimed = false
func physics_update(delta : float) -> void:
if applies(): return
play_char.gravity_apply(delta)
if input_management(): return
update_target()
move(delta)
func applies() -> bool:
if !play_char.is_on_floor() and play_char.velocity.y < 0.0:
transitioned.emit(self, "InairState")
return true
return false
func input_management() -> bool:
if !Input.is_action_pressed(aim_action):
transitioned.emit(self, play_char.walk_or_run if play_char.move_dir else "IdleState")
return true
if Input.is_action_just_pressed(unlock_action):
auto_lock_blocked = true
release_target()
elif Input.is_action_just_pressed(switch_target_action):
switch_target()
return false
func move(delta : float) -> void:
play_char.move_dir = Input.get_vector(play_char.move_left_action, play_char.move_right_action, play_char.move_forward_action, play_char.move_backward_action).rotated(-play_char.cam_holder.global_rotation.y)
if play_char.move_dir and play_char.is_on_floor():
play_char.velocity.x = lerp(play_char.velocity.x, play_char.move_dir.x * aim_move_speed, aim_move_accel * delta)
play_char.velocity.z = lerp(play_char.velocity.z, play_char.move_dir.y * aim_move_speed, aim_move_accel * delta)
else:
play_char.velocity.x = lerp(play_char.velocity.x, 0.0, play_char.move_deccel * delta)
play_char.velocity.z = lerp(play_char.velocity.z, 0.0, play_char.move_deccel * delta)
#---------- targeting ----------
func update_target() -> void:
var current : AimTarget = play_char.aim_target
#verrouillage existant : on le garde tant que distance et ligne de vue sont valides
#(l'angle avec la camera ne compte pas, le joueur peut deplacer la camera librement)
if is_instance_valid(current):
if is_target_valid(current, lose_range_margin, false): return
release_target()
#visee libre : auto-lock sur la meilleure cible proche du centre de la camera
var best : AimTarget = null
var best_angle : float = auto_lock_angle
for t in get_candidates():
var angle : float = get_angle_to_camera(t) - t.priority
if angle < best_angle:
best_angle = angle
best = t
if best == null:
auto_lock_blocked = false #le joueur a ecarte la camera : l'auto-lock est de nouveau permis
elif !auto_lock_blocked:
set_target(best)
func get_candidates() -> Array[AimTarget]:
var result : Array[AimTarget] = []
for node in get_tree().get_nodes_in_group("aim_targets"):
var t := node as AimTarget
if t and is_target_valid(t, 1.0, true): result.append(t)
return result
func is_target_valid(t : AimTarget, range_mult : float, check_angle : bool) -> bool:
if !t.enabled: return false
if play_char.global_position.distance_to(t.global_position) > throw_range * range_mult: return false
if check_angle and get_angle_to_camera(t) > max_aim_angle: return false
if check_line_of_sight and !has_line_of_sight(t): return false
return true
func get_angle_to_camera(t : AimTarget) -> float:
var cam : Camera3D = play_char.cam_holder.cam
var to_t : Vector3 = t.global_position - cam.global_position
return rad_to_deg((-cam.global_basis.z).angle_to(to_t))
func has_line_of_sight(t : AimTarget) -> bool:
var query := PhysicsRayQueryParameters3D.create(
play_char.cam_holder.cam.global_position, t.global_position, line_of_sight_mask, [play_char.get_rid()])
var hit : Dictionary = play_char.get_world_3d().direct_space_state.intersect_ray(query)
#pas d'obstacle, ou l'obstacle est le proprietaire de la cible lui-meme
return hit.is_empty() or hit["collider"].is_ancestor_of(t)
func switch_target() -> void:
#passe a la cible suivante, triee de gauche a droite par rapport a la camera (boucle)
var cam : Camera3D = play_char.cam_holder.cam
var forward : Vector3 = -cam.global_basis.z
var list : Array[AimTarget] = get_candidates()
#la cible actuelle reste dans la liste meme si la camera est decalee par rapport a elle
var current : AimTarget = play_char.aim_target
if is_instance_valid(current) and !list.has(current): list.append(current)
if list.size() < 2: return
list.sort_custom(func(a : AimTarget, b : AimTarget) -> bool:
return signed_angle(forward, a, cam) < signed_angle(forward, b, cam))
var idx : int = list.find(current)
idx = 0 if idx == -1 else (idx + 1) % list.size()
set_target(list[idx])
func signed_angle(forward : Vector3, t : AimTarget, cam : Camera3D) -> float:
var to_t : Vector3 = t.global_position - cam.global_position
return Vector2(forward.x, forward.z).angle_to(Vector2(to_t.x, to_t.z))
func set_target(t : AimTarget) -> void:
if play_char.aim_target == t: return
release_target()
play_char.aim_target = t
play_char.cam_holder.set_lock_target(t)
t.set_locked(true)
func release_target() -> void:
if !play_char: return
if is_instance_valid(play_char.aim_target): play_char.aim_target.set_locked(false)
play_char.aim_target = null
play_char.cam_holder.set_lock_target(null)

View file

@ -0,0 +1 @@
uid://dn5idrvu68k83

View file

@ -47,9 +47,16 @@ func input_management() -> void:
if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action):
transitioned.emit(self, "JumpState")
if Input.is_action_just_pressed(play_char.run_action):
if play_char.walk_or_run == "WalkState": play_char.walk_or_run = "RunState"
elif play_char.walk_or_run == "RunState": play_char.walk_or_run = "WalkState"
#if Input.is_action_just_pressed("player_aim_camera"):
if Input.is_action_just_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState")
if play_char.continious_run:
if Input.is_action_just_pressed(play_char.run_action):
if play_char.walk_or_run == "WalkState": play_char.walk_or_run = "RunState"
elif play_char.walk_or_run == "RunState": play_char.walk_or_run = "WalkState"
else:
play_char.walk_or_run = "RunState" if Input.is_action_pressed(play_char.run_action) else "WalkState"
func move(delta : float) -> void:
#manage the character movement

View file

@ -79,16 +79,16 @@ func jump() -> void:
var can_jump : bool = false #jump condition
#in air jump
#if !play_char.is_on_floor():
#if play_char.coyote_jump_on:
#play_char.jump_cooldown = play_char.jump_cooldown_ref
#play_char.coyote_jump_cooldown = -1.0 #so that the character cannot immediately make another coyote jump
#play_char.coyote_jump_on = false
#can_jump = true
#elif play_char.nb_jumps_in_air_allowed > 0:
#play_char.nb_jumps_in_air_allowed -= 1
#play_char.jump_cooldown = play_char.jump_cooldown_ref
#can_jump = true
if !play_char.is_on_floor():
if play_char.coyote_jump_on:
play_char.jump_cooldown = play_char.jump_cooldown_ref
play_char.coyote_jump_cooldown = -1.0 #so that the character cannot immediately make another coyote jump
play_char.coyote_jump_on = false
can_jump = true
elif play_char.nb_jumps_in_air_allowed > 0:
play_char.nb_jumps_in_air_allowed -= 1
play_char.jump_cooldown = play_char.jump_cooldown_ref
can_jump = true
#on floor jump
if play_char.is_on_floor():

View file

@ -59,6 +59,7 @@ var move_left_action : StringName
var move_right_action : StringName
var run_action : StringName
var jump_action : StringName
var aim_cam_action : StringName
@export_group("Model variables")
@export var model_rot_speed : float = 6.5
@ -81,6 +82,8 @@ var jump_action : StringName
#@onready var jump_particles = preload("../../PlayerCharacter/VFX/jump_particles_scene.tscn")
#@onready var land_particles = preload("../../PlayerCharacter/VFX/land_particles_scene.tscn")
var aim_target : AimTarget = null
func _ready():
#set move variables, and value references
move_speed = walk_speed
@ -106,6 +109,13 @@ func modify_model_orientation(delta : float):
var dir_target_angle : float
#lock-on : le modele fait face a la cible
if is_instance_valid(aim_target):
var to_target : Vector3 = aim_target.global_position - global_position
dir_target_angle = -Vector2(to_target.x, to_target.z).orthogonal().angle()
visual_root.rotation.y = rotate_toward(visual_root.rotation.y, dir_target_angle, model_rot_speed * delta)
return
#follow mode (model must follow the camera rotation)
#if the cam is in angled/aim mode
if cam_holder.cam_aimed and follow_cam_pos_when_aimed:

View file

@ -0,0 +1,74 @@
extends State
class_name RunState
var state_name : String = "Run"
var play_char : CharacterBody3D
func enter(play_char_ref : CharacterBody3D) -> void:
play_char = play_char_ref
verifications()
func verifications() -> void:
#play_char.godot_plush_skin.set_state("run")
play_char.walk_or_run = "RunState" #utilise par JumpState/InairState pour choisir les courbes en l'air
play_char.move_speed = play_char.run_speed
play_char.move_accel = play_char.run_accel
play_char.move_deccel = play_char.run_deccel
play_char.floor_snap_length = 1.0
if play_char.jump_cooldown > 0.0: play_char.jump_cooldown = -1.0
if play_char.nb_jumps_in_air_allowed < play_char.nb_jumps_in_air_allowed_ref: play_char.nb_jumps_in_air_allowed = play_char.nb_jumps_in_air_allowed_ref
if play_char.coyote_jump_cooldown < play_char.coyote_jump_cooldown_ref: play_char.coyote_jump_cooldown = play_char.coyote_jump_cooldown_ref
if play_char.has_cut_jump: play_char.has_cut_jump = false
func physics_update(delta : float) -> void:
applies()
play_char.gravity_apply(delta)
input_management()
move(delta)
func applies() -> void:
if !play_char.is_on_floor() and !play_char.is_on_wall():
if play_char.velocity.y < 0.0:
transitioned.emit(self, "InairState")
if play_char.is_on_floor():
if play_char.jump_buff_on:
#apply jump buffering
play_char.buffered_jump = true
play_char.jump_buff_on = false
transitioned.emit(self, "JumpState")
func input_management() -> void:
if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action):
transitioned.emit(self, "JumpState")
if play_char.continious_run:
#course continue : un nouvel appui sur la touche repasse a la marche
if Input.is_action_just_pressed(play_char.run_action):
stop_running()
else:
#course maintenue : on court tant que la touche est enfoncee
if !Input.is_action_pressed(play_char.run_action):
stop_running()
func stop_running() -> void:
play_char.walk_or_run = "WalkState"
transitioned.emit(self, "WalkState")
func move(delta : float) -> void:
play_char.move_dir = Input.get_vector(play_char.move_left_action, play_char.move_right_action, play_char.move_forward_action, play_char.move_backward_action).rotated(-play_char.cam_holder.global_rotation.y)
if play_char.move_dir and play_char.is_on_floor():
#apply smooth move
play_char.velocity.x = lerp(play_char.velocity.x, play_char.move_dir.x * play_char.move_speed, play_char.move_accel * delta)
play_char.velocity.z = lerp(play_char.velocity.z, play_char.move_dir.y * play_char.move_speed, play_char.move_accel * delta)
else:
if !play_char.continious_run: play_char.walk_or_run = "WalkState"
transitioned.emit(self, "IdleState")

View file

@ -0,0 +1 @@
uid://dpcfffs3vt5co

View file

@ -49,7 +49,11 @@ func input_management() -> void:
if Input.is_action_pressed(play_char.jump_action) if play_char.auto_jump else Input.is_action_just_pressed(play_char.jump_action) :
transitioned.emit(self, "JumpState")
if Input.is_action_just_pressed(play_char.run_action):
if Input.is_action_just_pressed(play_char.aim_cam_action):
transitioned.emit(self, "AimState")
var wants_run : bool = Input.is_action_just_pressed(play_char.run_action) if play_char.continious_run else Input.is_action_pressed(play_char.run_action)
if wants_run:
play_char.walk_or_run = "RunState"
transitioned.emit(self, "RunState")

View file

@ -0,0 +1,66 @@
extends Marker3D
class_name AimTarget
signal locked_changed(is_locked : bool)
@export var enabled : bool = true
@export var priority : float = 0.0 #plus c'est haut, plus la cible est favorisee
@export_group("Indicator")
@export var indicator : Node3D #optionnel : ton propre visuel (remplace le losange par defaut)
@export var show_default_diamond : bool = true
@export var diamond_size : float = 0.3
@export var diamond_color : Color = Color(1.0, 0.85, 0.2, 0.95)
@export var diamond_offset : Vector3 = Vector3.ZERO #decalage par rapport a la node (ex. (0, 0.5, 0) pour le mettre au-dessus)
var is_locked : bool = false
func _ready() -> void:
add_to_group("aim_targets")
if indicator == null and show_default_diamond:
indicator = create_diamond()
add_child(indicator)
if indicator: indicator.visible = false
func create_diamond() -> MeshInstance3D:
#carre incline a 45 degres, oriente vers la camera
#(la rotation est appliquee directement aux sommets, car le billboard ignore la rotation de la node)
var half : float = diamond_size * 0.3
var corners : Array[Vector3] = [
Vector3(-half, -half, 0.0),
Vector3(half, -half, 0.0),
Vector3(half, half, 0.0),
Vector3(-half, half, 0.0),
]
for i in corners.size():
corners[i] = corners[i].rotated(Vector3.BACK, deg_to_rad(45.0))
var st := SurfaceTool.new()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
for i in [0, 1, 2, 0, 2, 3]:
st.add_vertex(corners[i])
var mat := StandardMaterial3D.new()
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
mat.albedo_color = diamond_color
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
mat.billboard_mode = BaseMaterial3D.BILLBOARD_ENABLED
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
mat.no_depth_test = true #reste visible meme a travers le modele de la cible
mat.render_priority = 100
var mesh_instance := MeshInstance3D.new()
mesh_instance.mesh = st.commit()
mesh_instance.material_override = mat
mesh_instance.position = diamond_offset
mesh_instance.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
return mesh_instance
func set_locked(value : bool) -> void:
if is_locked == value: return
is_locked = value
if indicator: indicator.visible = value
locked_changed.emit(value)

View file

@ -0,0 +1 @@
uid://ce2wj6d8xb055

View file

@ -109,7 +109,7 @@ pause={
player_aim_camera={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(251, 16),"global_position":Vector2(263, 76),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":4,"pressure":0.0,"pressed":true,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null)
]
}
player_zoom_camera_in={
@ -144,6 +144,16 @@ player_crouch={
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":7,"pressure":0.0,"pressed":true,"script":null)
]
}
player_aim_unlock={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null)
]
}
player_aim_switch_target={
"deadzone": 0.2,
"events": [Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":13,"pressure":0.0,"pressed":true,"script":null)
]
}
[physics]

View file

@ -5,6 +5,7 @@
[ext_resource type="Texture2D" uid="uid://cm5m7nr7dugjd" path="res://assets/textures/grids/Purple/texture_09.png" id="3_tefeu"]
[ext_resource type="Texture2D" uid="uid://djg8y25y06h5n" path="res://assets/textures/grids/Green/texture_09.png" id="4_o6xl0"]
[ext_resource type="Texture2D" uid="uid://hu5rfl6qr2nv" path="res://assets/textures/grids/Red/texture_09.png" id="5_o6xl0"]
[ext_resource type="Script" uid="uid://ce2wj6d8xb055" path="res://game/player/actions/AimTarget.gd" id="6_85g3d"]
[ext_resource type="PackedScene" uid="uid://dwxpt0s7vn36k" path="res://game/player/PlayerCharacter.tscn" id="6_o6xl0"]
[ext_resource type="PackedScene" uid="uid://d1mcef8gl66j" path="res://scenes/pause_menu.tscn" id="6_tefeu"]
[ext_resource type="PackedScene" uid="uid://di22cs2qposdm" path="res://game/ui/ui.tscn" id="8_tipki"]
@ -79,23 +80,35 @@ use_collision = true
size = Vector3(3, 3, 3)
[node name="target" type="CSGBox3D" parent="map" unique_id=1890903851]
transform = Transform3D(0.99887395, 0, -0.04744184, 0, 1, 0, 0.04744184, 0, 0.99887395, 7.7646155, 2.1005468, -0.10642481)
transform = Transform3D(0.99887395, 0, -0.04744184, 0, 1, 0, 0.04744184, 0, 0.99887395, 7.7646155, 2.4045455, -0.10642481)
material_override = SubResource("StandardMaterial3D_tipki")
use_collision = true
size = Vector3(0.5, 0.5, 0.5)
[node name="AimTarget" type="Marker3D" parent="map/target" unique_id=807674215]
transform = Transform3D(1, 0, 3.7252903e-09, 0, 1, 0, -3.7252903e-09, 0, 1, 0, 0.030708313, 0)
script = ExtResource("6_85g3d")
[node name="target2" type="CSGBox3D" parent="map" unique_id=1489015232]
transform = Transform3D(0.99887395, 0, -0.04744184, 0, 1, 0, 0.04744184, 0, 0.99887395, 7.7646155, 2.1005468, 2.931901)
transform = Transform3D(0.99887395, 0, -0.04744184, 0, 1, 0, 0.04744184, 0, 0.99887395, 7.7646155, 0.20568156, 2.931901)
material_override = SubResource("StandardMaterial3D_tipki")
use_collision = true
size = Vector3(0.5, 0.5, 0.5)
[node name="AimTarget" type="Marker3D" parent="map/target2" unique_id=1618946008]
transform = Transform3D(1, 0, 3.7252903e-09, 0, 1, 0, -3.7252903e-09, 0, 1, 0, 0.030708313, 0)
script = ExtResource("6_85g3d")
[node name="target3" type="CSGBox3D" parent="map" unique_id=1721457742]
transform = Transform3D(0.99887395, 0, -0.04744184, 0, 1, 0, 0.04744184, 0, 0.99887395, 7.7646155, 2.1005468, 5.7028685)
transform = Transform3D(0.99887395, 0, -0.04744184, 0, 1, 0, 0.04744184, 0, 0.99887395, 7.7646155, 1.7272058, 8.399635)
material_override = SubResource("StandardMaterial3D_tipki")
use_collision = true
size = Vector3(0.5, 0.5, 0.5)
[node name="AimTarget" type="Marker3D" parent="map/target3" unique_id=1848628150]
transform = Transform3D(1, 0, 3.7252903e-09, 0, 1, 0, -3.7252903e-09, 0, 1, 0, 0.030708313, 0)
script = ExtResource("6_85g3d")
[node name="Ui" parent="." unique_id=1881560149 instance=ExtResource("8_tipki")]
[node name="PauseMenu" parent="." unique_id=871841579 instance=ExtResource("6_tefeu")]