Add ui hints
This commit is contained in:
parent
968d03053b
commit
e115200194
|
|
@ -20,6 +20,11 @@ signal candidate_changed(sent : SentPokemon) #pokemon montable a portee (null =
|
||||||
@export var swallow_jump_on_mount : bool = true #si A sert aussi a sauter : l'appui qui monte ne declenche pas de saut
|
@export var swallow_jump_on_mount : bool = true #si A sert aussi a sauter : l'appui qui monte ne declenche pas de saut
|
||||||
@export var camera_follow_speed : float = 8.0 #vitesse a laquelle la camera monte a hauteur de selle
|
@export var camera_follow_speed : float = 8.0 #vitesse a laquelle la camera monte a hauteur de selle
|
||||||
|
|
||||||
|
@export_group("Hints HUD")
|
||||||
|
@export var mount_hint_text : String = "Grimper"
|
||||||
|
@export var dismount_hint_text : String = "Descendre"
|
||||||
|
@export var hint_priority : int = 10
|
||||||
|
|
||||||
const GROUNDED_STATES : Array[String] = ["Idle", "Walk", "Run"] #monter / descendre n'est possible que depuis ces etats
|
const GROUNDED_STATES : Array[String] = ["Idle", "Walk", "Run"] #monter / descendre n'est possible que depuis ces etats
|
||||||
|
|
||||||
@onready var player : PlayerCharacter = get_parent()
|
@onready var player : PlayerCharacter = get_parent()
|
||||||
|
|
@ -51,6 +56,9 @@ func _ready() -> void:
|
||||||
key.physical_keycode = KEY_F
|
key.physical_keycode = KEY_F
|
||||||
InputMap.action_add_event(dismount_action, key))
|
InputMap.action_add_event(dismount_action, key))
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
Hints.clear_context(self)
|
||||||
|
|
||||||
func _ensure_action(action : StringName, add_events : Callable) -> void:
|
func _ensure_action(action : StringName, add_events : Callable) -> void:
|
||||||
if InputMap.has_action(action): return
|
if InputMap.has_action(action): return
|
||||||
InputMap.add_action(action)
|
InputMap.add_action(action)
|
||||||
|
|
@ -61,7 +69,10 @@ func is_mounted() -> bool:
|
||||||
|
|
||||||
func _physics_process(_delta : float) -> void:
|
func _physics_process(_delta : float) -> void:
|
||||||
if mount != null:
|
if mount != null:
|
||||||
if Input.is_action_just_pressed(dismount_action) and _can_switch_now():
|
var can_dismount : bool = _can_switch_now()
|
||||||
|
if can_dismount: Hints.set_context(self, dismount_action, dismount_hint_text, hint_priority)
|
||||||
|
else: Hints.clear_context(self)
|
||||||
|
if Input.is_action_just_pressed(dismount_action) and can_dismount:
|
||||||
dismount()
|
dismount()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -123,6 +134,8 @@ func _set_candidate(s : SentPokemon) -> void:
|
||||||
if s == candidate: return
|
if s == candidate: return
|
||||||
candidate = s
|
candidate = s
|
||||||
candidate_changed.emit(s)
|
candidate_changed.emit(s)
|
||||||
|
if s != null: Hints.set_context(self, mount_action, mount_hint_text, hint_priority)
|
||||||
|
else: Hints.clear_context(self)
|
||||||
|
|
||||||
#---------- monter / descendre ----------
|
#---------- monter / descendre ----------
|
||||||
|
|
||||||
|
|
@ -133,6 +146,7 @@ func mount_up(s : SentPokemon) -> void:
|
||||||
s.rider = player
|
s.rider = player
|
||||||
s.recalled.connect(_on_mount_recalled)
|
s.recalled.connect(_on_mount_recalled)
|
||||||
_set_candidate(null)
|
_set_candidate(null)
|
||||||
|
Hints.set_context(self, dismount_action, dismount_hint_text, hint_priority)
|
||||||
|
|
||||||
player.is_mounted = true
|
player.is_mounted = true
|
||||||
player.enter_mount_stats(profile.mount_speed, profile.mount_accel, profile.mount_deccel,
|
player.enter_mount_stats(profile.mount_speed, profile.mount_accel, profile.mount_deccel,
|
||||||
|
|
@ -151,6 +165,7 @@ func dismount() -> void:
|
||||||
|
|
||||||
player.is_mounted = false
|
player.is_mounted = false
|
||||||
player.exit_mount_stats()
|
player.exit_mount_stats()
|
||||||
|
Hints.clear_context(self)
|
||||||
_release_blocked_states_next_frame()
|
_release_blocked_states_next_frame()
|
||||||
|
|
||||||
visual_root.position -= _seat_applied
|
visual_root.position -= _seat_applied
|
||||||
|
|
|
||||||
|
|
@ -234,3 +234,8 @@ func release_target() -> void:
|
||||||
if is_instance_valid(play_char.aim_target): play_char.aim_target.set_locked(false)
|
if is_instance_valid(play_char.aim_target): play_char.aim_target.set_locked(false)
|
||||||
play_char.aim_target = null
|
play_char.aim_target = null
|
||||||
play_char.cam_holder.set_lock_target(null)
|
play_char.cam_holder.set_lock_target(null)
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return [
|
||||||
|
{"action": switch_target_action, "text": "Changer de cible"}
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -70,3 +70,6 @@ func move(delta : float) -> void:
|
||||||
#apply smooth stop
|
#apply smooth stop
|
||||||
play_char.velocity.x = lerp(play_char.velocity.x, 0.0, play_char.move_deccel * delta)
|
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)
|
play_char.velocity.z = lerp(play_char.velocity.z, 0.0, play_char.move_deccel * delta)
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return [{"action": &"player_jump", "text": "Sauter"}]
|
||||||
|
|
|
||||||
|
|
@ -110,4 +110,5 @@ func jump() -> void:
|
||||||
play_char.squash_and_strech(1.12, 0.1)
|
play_char.squash_and_strech(1.12, 0.1)
|
||||||
#play_char.particles_manager.display_particles(play_char.jump_particles, play_char)
|
#play_char.particles_manager.display_particles(play_char.jump_particles, play_char)
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return [{"action": &"player_jump", "text": "Sauter"}]
|
||||||
|
|
|
||||||
|
|
@ -14,3 +14,6 @@ func enter(play_char_ref : CharacterBody3D) -> void:
|
||||||
play_char.move_deccel = profile.mount_deccel
|
play_char.move_deccel = profile.mount_deccel
|
||||||
# instancier profile.mount_scene_override ou profile.species.model_scene,
|
# instancier profile.mount_scene_override ou profile.species.model_scene,
|
||||||
# le positionner, y attacher play_char selon seat_offset...
|
# le positionner, y attacher play_char selon seat_offset...
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return [{"action": &"player_dismount", "text": "Descendre"}] # remplace par le nom réel de ton action
|
||||||
|
|
|
||||||
|
|
@ -68,3 +68,6 @@ func move(delta : float) -> void:
|
||||||
else:
|
else:
|
||||||
if !play_char.continious_run: play_char.walk_or_run = "WalkState"
|
if !play_char.continious_run: play_char.walk_or_run = "WalkState"
|
||||||
transitioned.emit(self, "IdleState")
|
transitioned.emit(self, "IdleState")
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return [{"action": &"player_jump", "text": "Sauter"}]
|
||||||
|
|
|
||||||
|
|
@ -19,3 +19,6 @@ func update(_delta : float) -> void:
|
||||||
func physics_update(_delta : float) -> void:
|
func physics_update(_delta : float) -> void:
|
||||||
#physics_process update
|
#physics_process update
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return []
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ func _ready() -> void:
|
||||||
initial_state.enter(char_ref)
|
initial_state.enter(char_ref)
|
||||||
curr_state = initial_state
|
curr_state = initial_state
|
||||||
curr_state_name = curr_state.state_name
|
curr_state_name = curr_state.state_name
|
||||||
|
Hints.set_state_hints(curr_state.get_hints())
|
||||||
|
|
||||||
func _process(delta : float) -> void:
|
func _process(delta : float) -> void:
|
||||||
if curr_state: curr_state.update(delta)
|
if curr_state: curr_state.update(delta)
|
||||||
|
|
@ -73,6 +74,7 @@ func on_state_child_transition(state : State, new_state_name : String) -> void:
|
||||||
|
|
||||||
curr_state = new_state
|
curr_state = new_state
|
||||||
curr_state_name = curr_state.state_name
|
curr_state_name = curr_state.state_name
|
||||||
|
Hints.set_state_hints(curr_state.get_hints())
|
||||||
|
|
||||||
func set_state_blocked(state_name : String, blocked : bool) -> void:
|
func set_state_blocked(state_name : String, blocked : bool) -> void:
|
||||||
if blocked: blocked_states[state_name.to_lower()] = true
|
if blocked: blocked_states[state_name.to_lower()] = true
|
||||||
|
|
|
||||||
|
|
@ -294,3 +294,8 @@ func _release_aim() -> void:
|
||||||
play_char.aim_target = null
|
play_char.aim_target = null
|
||||||
play_char.cam_holder.set_lock_target(null)
|
play_char.cam_holder.set_lock_target(null)
|
||||||
play_char.cam_holder.cam_aimed = false
|
play_char.cam_holder.cam_aimed = false
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return [
|
||||||
|
{"action": cancel_action, "text": "Annuler le lancer"},
|
||||||
|
]
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,5 @@ func move(delta : float) -> void:
|
||||||
else:
|
else:
|
||||||
transitioned.emit(self, "IdleState")
|
transitioned.emit(self, "IdleState")
|
||||||
|
|
||||||
|
func get_hints() -> Array:
|
||||||
|
return [{"action": &"player_jump", "text": "Sauter"}]
|
||||||
|
|
|
||||||
42
game/ui/hints/hints.gd
Normal file
42
game/ui/hints/hints.gd
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
signal changed
|
||||||
|
|
||||||
|
var _state_hints : Array = [] # [{action, text}]
|
||||||
|
var _context_hints : Dictionary = {} # clé (objet source) -> {action, text, priority}
|
||||||
|
|
||||||
|
#---------- hints d'état (appelés par la StateMachine) ----------
|
||||||
|
|
||||||
|
func set_state_hints(list : Array) -> void:
|
||||||
|
_state_hints = list
|
||||||
|
changed.emit()
|
||||||
|
|
||||||
|
#---------- hints de contexte (appelés par monture, PNJ, etc.) ----------
|
||||||
|
|
||||||
|
func set_context(source : Object, action : StringName, text : String, priority : int = 0) -> void:
|
||||||
|
var h : Dictionary = {"action": action, "text": text, "priority": priority}
|
||||||
|
if _context_hints.get(source) == h: return
|
||||||
|
_context_hints[source] = h
|
||||||
|
changed.emit()
|
||||||
|
|
||||||
|
func clear_context(source : Object) -> void:
|
||||||
|
if _context_hints.erase(source): changed.emit()
|
||||||
|
|
||||||
|
#---------- lecture (par le HUD) ----------
|
||||||
|
|
||||||
|
func get_visible() -> Array:
|
||||||
|
#nettoie les sources détruites sans avoir appelé clear_context
|
||||||
|
for key in _context_hints.keys():
|
||||||
|
if !is_instance_valid(key): _context_hints.erase(key)
|
||||||
|
|
||||||
|
var ctx : Array = _context_hints.values()
|
||||||
|
ctx.sort_custom(func(a, b): return a.priority > b.priority)
|
||||||
|
|
||||||
|
#le contexte passe avant l'état ; une même action n'apparaît qu'une fois
|
||||||
|
var result : Array = []
|
||||||
|
var used : Dictionary = {}
|
||||||
|
for h in ctx + _state_hints:
|
||||||
|
if used.has(h.action): continue
|
||||||
|
used[h.action] = true
|
||||||
|
result.append(h)
|
||||||
|
return result
|
||||||
1
game/ui/hints/hints.gd.uid
Normal file
1
game/ui/hints/hints.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bqapxkrub0fcs
|
||||||
33
game/ui/hints/hints_hud.gd
Normal file
33
game/ui/hints/hints_hud.gd
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
extends MarginContainer
|
||||||
|
|
||||||
|
@onready var rows : HBoxContainer = $HBoxContainer
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
Hints.changed.connect(refresh)
|
||||||
|
refresh()
|
||||||
|
|
||||||
|
func refresh() -> void:
|
||||||
|
for c in rows.get_children():
|
||||||
|
rows.remove_child(c)
|
||||||
|
c.queue_free()
|
||||||
|
for h in Hints.get_visible():
|
||||||
|
rows.add_child(make_row(h.action, h.text))
|
||||||
|
|
||||||
|
func make_row(action : StringName, text : String) -> HBoxContainer:
|
||||||
|
var row := HBoxContainer.new()
|
||||||
|
|
||||||
|
var tex := ControllerIconTexture.new()
|
||||||
|
tex.path = String(action) #même chose que le champ "path" dans ta scène
|
||||||
|
|
||||||
|
var icon := TextureRect.new()
|
||||||
|
icon.texture = tex
|
||||||
|
icon.custom_minimum_size = Vector2(40, 40)
|
||||||
|
icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
|
||||||
|
icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
||||||
|
row.add_child(icon)
|
||||||
|
|
||||||
|
var label := Label.new()
|
||||||
|
label.text = text
|
||||||
|
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||||
|
row.add_child(label)
|
||||||
|
return row
|
||||||
1
game/ui/hints/hints_hud.gd.uid
Normal file
1
game/ui/hints/hints_hud.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cj73boctbuqvj
|
||||||
|
|
@ -1,30 +1,10 @@
|
||||||
[gd_scene format=3 uid="uid://di22cs2qposdm"]
|
[gd_scene format=3 uid="uid://di22cs2qposdm"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://7hglx6nfu063" path="res://addons/controller_icons/objects/ControllerIconTexture.gd" id="1_4xhdt"]
|
|
||||||
[ext_resource type="Script" uid="uid://rgm6aitwyxdv" path="res://game/ui/hud/save_hud.gd" id="1_euh0j"]
|
[ext_resource type="Script" uid="uid://rgm6aitwyxdv" path="res://game/ui/hud/save_hud.gd" id="1_euh0j"]
|
||||||
|
[ext_resource type="Script" uid="uid://cj73boctbuqvj" path="res://game/ui/hints/hints_hud.gd" id="2_8ujol"]
|
||||||
[ext_resource type="Script" uid="uid://b3ddqgiawrh5c" path="res://game/ui/hud/team_hud.gd" id="2_lkjh2"]
|
[ext_resource type="Script" uid="uid://b3ddqgiawrh5c" path="res://game/ui/hud/team_hud.gd" id="2_lkjh2"]
|
||||||
[ext_resource type="Script" uid="uid://c3b263k0gt0ck" path="res://game/ui/hide_during_battle.gd" id="3_8ujol"]
|
[ext_resource type="Script" uid="uid://c3b263k0gt0ck" path="res://game/ui/hide_during_battle.gd" id="3_8ujol"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_uyiaf"]
|
|
||||||
|
|
||||||
[sub_resource type="Texture2D" id="Texture2D_3agn1"]
|
|
||||||
resource_local_to_scene = false
|
|
||||||
resource_name = ""
|
|
||||||
script = ExtResource("1_4xhdt")
|
|
||||||
path = "player_jump"
|
|
||||||
metadata/_custom_type_script = "uid://7hglx6nfu063"
|
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_3agn1"]
|
|
||||||
|
|
||||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_0fvdv"]
|
|
||||||
|
|
||||||
[sub_resource type="Texture2D" id="Texture2D_4xhdt"]
|
|
||||||
resource_local_to_scene = false
|
|
||||||
resource_name = ""
|
|
||||||
script = ExtResource("1_4xhdt")
|
|
||||||
path = "ui_accept"
|
|
||||||
metadata/_custom_type_script = "uid://7hglx6nfu063"
|
|
||||||
|
|
||||||
[node name="Ui" type="CanvasLayer" unique_id=1492671226]
|
[node name="Ui" type="CanvasLayer" unique_id=1492671226]
|
||||||
|
|
||||||
[node name="SaveHUD" type="CanvasLayer" parent="." unique_id=319200051]
|
[node name="SaveHUD" type="CanvasLayer" parent="." unique_id=319200051]
|
||||||
|
|
@ -49,53 +29,13 @@ grow_horizontal = 0
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
theme_override_constants/margin_right = 10
|
theme_override_constants/margin_right = 10
|
||||||
theme_override_constants/margin_bottom = 10
|
theme_override_constants/margin_bottom = 10
|
||||||
|
script = ExtResource("2_8ujol")
|
||||||
|
|
||||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer" unique_id=1235437041]
|
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer" unique_id=1235437041]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 24
|
||||||
[node name="PanelContainer2" type="PanelContainer" parent="MarginContainer/HBoxContainer" unique_id=429339024]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_styles/panel = SubResource("StyleBoxEmpty_uyiaf")
|
|
||||||
|
|
||||||
[node name="HFlowContainer3" type="HFlowContainer" parent="MarginContainer/HBoxContainer/PanelContainer2" unique_id=165290387]
|
|
||||||
custom_minimum_size = Vector2(130, -1)
|
|
||||||
layout_mode = 2
|
|
||||||
alignment = 2
|
alignment = 2
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="MarginContainer/HBoxContainer/PanelContainer2/HFlowContainer3" unique_id=895869050]
|
|
||||||
custom_minimum_size = Vector2(40, 40)
|
|
||||||
custom_maximum_size = Vector2(40, 40)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
texture = SubResource("Texture2D_3agn1")
|
|
||||||
expand_mode = 1
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="MarginContainer/HBoxContainer/PanelContainer2/HFlowContainer3" unique_id=1494282096]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Sauter"
|
|
||||||
label_settings = SubResource("LabelSettings_3agn1")
|
|
||||||
|
|
||||||
[node name="PanelContainer" type="PanelContainer" parent="MarginContainer/HBoxContainer" unique_id=525836706]
|
|
||||||
layout_mode = 2
|
|
||||||
theme_override_styles/panel = SubResource("StyleBoxEmpty_0fvdv")
|
|
||||||
|
|
||||||
[node name="HFlowContainer2" type="HFlowContainer" parent="MarginContainer/HBoxContainer/PanelContainer" unique_id=534508482]
|
|
||||||
custom_minimum_size = Vector2(130, -1)
|
|
||||||
layout_mode = 2
|
|
||||||
alignment = 2
|
|
||||||
|
|
||||||
[node name="TextureRect" type="TextureRect" parent="MarginContainer/HBoxContainer/PanelContainer/HFlowContainer2" unique_id=729252705]
|
|
||||||
custom_minimum_size = Vector2(40, 40)
|
|
||||||
layout_mode = 2
|
|
||||||
size_flags_vertical = 3
|
|
||||||
texture = SubResource("Texture2D_4xhdt")
|
|
||||||
expand_mode = 1
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="MarginContainer/HBoxContainer/PanelContainer/HFlowContainer2" unique_id=701166371]
|
|
||||||
layout_mode = 2
|
|
||||||
text = "Accepter"
|
|
||||||
label_settings = SubResource("LabelSettings_3agn1")
|
|
||||||
|
|
||||||
[node name="HideDuringBattle" type="Node" parent="MarginContainer" unique_id=1229951221]
|
[node name="HideDuringBattle" type="Node" parent="MarginContainer" unique_id=1229951221]
|
||||||
script = ExtResource("3_8ujol")
|
script = ExtResource("3_8ujol")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ ControllerIcons="*uid://b7ho1rjcpht1d"
|
||||||
GameData="*uid://d4beiel88cwc7"
|
GameData="*uid://d4beiel88cwc7"
|
||||||
UiAudio="*uid://7e7fe2xk3aue"
|
UiAudio="*uid://7e7fe2xk3aue"
|
||||||
LoadingScreen="*uid://ckyjxhrfhaqlc"
|
LoadingScreen="*uid://ckyjxhrfhaqlc"
|
||||||
|
Hints="*uid://bqapxkrub0fcs"
|
||||||
Pokedex="*uid://dijnkrewbwgmx"
|
Pokedex="*uid://dijnkrewbwgmx"
|
||||||
MountRegistry="*uid://u4gskwbwm0b0"
|
MountRegistry="*uid://u4gskwbwm0b0"
|
||||||
DebugPokemonPanel="*uid://b3058rssf6ud5"
|
DebugPokemonPanel="*uid://b3058rssf6ud5"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue