Conversation
|
Play this branch at https://play.threadbare.game/branches/endlessm/wjt/move-interact-verb-action-to-hud/. (This launches the game from the start, not directly at the change(s) in this pull request.) |
|
This is a draft for a number of reasons, not least that But another thing I realised while testing this… I had really hoped that we could avoid needing the ScreenOverlay CanvasLayer, on the basis that we seem to get away OK with the grapple direction arrow on the player being smaller when the view zooms out, and because we could then just WONTFIX #725. However while testing this I happened to look at When I first prototyped this I put a static, dimmed/semitransparent arrow above all interactable objects, with the currently-targetted one (if any) bouncing and fully opaque. This looked really busy in areas with many interactable objects, such as sequence puzzles. If we are happy to only show a single arrow at a time (not sure!) then we could instead have the Otherwise... maybe we are stuck with the ScreenOverlay (but could we use the InputHud autoload which is guaranteed always to be present?) and then we'll have to solve the dizzying effect still. |
I see that in code you create a Marker2D and then instantiate the
In my opinion it doesn't look that bad. This Guardian is an instance of Talker. Maybe it can just be a StaticBody2D with the AnimatedSprite2D (scaled at 1.5), plus the TalkBehavior, plus the InteractArea as children. Like a one-off node for this particular scene. I also would like to say goodbye to ScreenOverlay :)
I remember watching a screenshare with the multiple semi-transparent arrows and yes, my first impression was that it was a bit busy. I like it one at the time, like in this draft. When you say you would like to reuse a single arrow, is it for consistency? For optimization? I wouldn't mind having each InteractArea with their own arrow that gets disabled/enabled, at least as a first step.
|
|
After playing some more... I really like where this is going. Maybe the "[Space] Talk to..." in the HUD can have a visual/audio clue when it changes (for later). Also I wonder if the arrow is too tiny for the Eternal Loom or other big things to interact, but I guess it's fine! |
That's what I plan to do. (And in fact you're on the right track that this was the cause of the misalignment bug - in one code path I set the position on the marker, and in the other I set the position on the indicator.) I was hoping to have a clever tool script migrate all the scenes that set
The reason I didn't do this is that we want (I think?) the indicator to be consistent between every interactable thing, so it would be manual work each time to put the indicator in place, and then a nightmare if we want to change how it works later!
OK!
True!
👍🏻
It was for showing a single arrow in ScreenOverlay/InputHud, moved around to the current target. I don't think there is likely to be a performance issue with one arrow per target but all bar one being invisible. OK, I will continue down this path. |
478f259 to
07b7111
Compare
6fac8b9 to
54b0dc1
Compare
|
I finished migrating all existing
I tweaked the Stella tortoise by hand. I also tried adding a little sound effect whenever the interact target changes. I think it's good? I wondered about making the "(A) Talk to Sigurd" label emit particles in this case too but decided that's too much, and visual design is not my forté. |
|
One more problem I noticed: the arrow is in the world layer so is affected by weather. |
54b0dc1 to
ea56a0e
Compare
ea56a0e to
8de64ce
Compare
8de64ce to
a997d89
Compare
df42d84 to
07367b9
Compare
07367b9 to
00c6712
Compare
Instead of showing text over the object in the world, show it on the HUD at the bottom of the screen, in place of the "Interact" label. Show a bouncing red arrow above the currently-targetted interactable entity. Show nothing above interactable entities that are not currently targetted, but define an "idle" animation for this case so that we could in theory change this later just by adjusting the animation. Define the arrow position with a Marker2D attached to the InteractArea. Migrate all existing interact_label_position values to a new Marker2D node on each - these will not all be correct, but some of them might be. Manually adjust some, including the tricky case of the Stella tortoise. (Doing this by moving a Marker2D around in the editor is so much easier than when I did it by editing Vector2 values by hand!) For some cases where the default position - 64px above the InteractArea - is good enough, I removed the Marker2D for a simpler scene & smaller diff. Make all InteractArea nodes visible. (In a number of cases we previously hid them to reduce the visual clutter, but this would hide the arrow.) I may have missed some but we can fix them as we find them. At runtime, if no Marker2D is provided, place one 64px above the InteractArea node - better than nothing. Adjust the logic in character_sight.gd to only emit interact_area_changed if it actually does change, rather than just because the player moved so that a second object is in range without changing the "best" object. (This has no visible effect but was necessary to add a sound effect on change, which I tried then removed.) Resolves #2114
00c6712 to
e9f0903
Compare
|
|
||
| ## Emitted when [method can_interact] will return a different value. | ||
| signal can_interact_changed | ||
| ## Emitted when the entity the player is able to interact with changes (possibly |
There was a problem hiding this comment.
At first read I though that you were trying to say either "the entity" or "the player", not both. But after a second read, I got it!
There was a problem hiding this comment.
Good point, it's a tricky sentence...
| ## Returns the human-readable text of [member character]'s current interact | ||
| ## action (e.g. [code]"Talk"[/code]), or [code]""[/code] (empty string) if | ||
| ## [member character] cannot currently interact with anything. Use [signal | ||
| ## interact_action_changed] to monitor for changes. | ||
| func get_interact_action() -> String: |
| if marker and _indicator: | ||
| marker.remove_child(_indicator) | ||
| marker = new_value | ||
| if marker and _indicator: | ||
| marker.add_child(_indicator) |
| # Vaguely sensible default position | ||
| marker.position = Vector2(0, -64) |
There was a problem hiding this comment.
👍 as you say in the PR description, is better than nothing.
| func set_bouncing(new_value: bool) -> void: | ||
| bouncing = new_value | ||
| if animation_player: | ||
| animation_player.play(&"bounce" if new_value else &"idle") |
There was a problem hiding this comment.
I like that the bounce is done through AnimationPlayer!
| if player_interaction: | ||
| var action := player_interaction.get_interact_action() | ||
| interact_input_hint.visible = not action.is_empty() | ||
| interact_input_hint.text = action | ||
| else: | ||
| interact_input_hint.visible = false |

Instead of showing text over the object in the world, show it on the HUD
at the bottom of the screen, in place of the "Interact" label.
Show a bouncing red arrow above the currently-targetted interactable
entity. Show nothing above interactable entities that are not currently
targetted, but define an "idle" animation for this case so that we could
in theory change this later just by adjusting the animation.
Define the arrow position with a Marker2D attached to the InteractArea.
Migrate all existing interact_label_position values to a new Marker2D
node on each - these will not all be correct, but some of them might be.
Manually adjust some, including the tricky case of the Stella tortoise.
(Doing this by moving a Marker2D around in the editor is so much easier
than when I did it by editing Vector2 values by hand!) For some cases
where the default position - 64px above the InteractArea - is good
enough, I removed the Marker2D for a simpler scene & smaller diff.
Make all InteractArea nodes visible. (In a number of cases we previously
hid them to reduce the visual clutter, but this would hide the arrow.) I
may have missed some but we can fix them as we find them.
At runtime, if no Marker2D is provided, place one 64px
above the InteractArea node - better than nothing.
Adjust the logic in character_sight.gd to only emit
interact_area_changed if it actually does change, rather than just
because the player moved so that a second object is in range without
changing the "best" object. (This has no visible effect but was
necessary to add a sound effect on change, which I tried then removed.)
Resolves #2114