Phazorknight / Cogito

Immersive Sim Template Project for GODOT 4
MIT License
670 stars 72 forks source link

Separate interactable detection from PlayerInteractionComponent #170

Closed aronand closed 2 months ago

aronand commented 2 months ago

Currently PlayerInteractionComponent handles both player interactions and detecting interactables in the player's view.

I propose that the detection functionality is decoupled from the controller and given to the RayCast3D that the Player holds. This node will then send signals whenever an interactable comes into view or leaves the view, to which the controller will respond to accordingly.

I've done some preliminary work and testing on it here: https://github.com/aronand/Cogito/tree/InteractionRayCast

Currently the implementation is mostly functional, with only double interaction component seemingly not working. Due to the way that the UI prompts work however, I currently have to hack them by updating them each frame, and to fix this, changes will most likely also impact the UI.

aronand commented 2 months ago

In fact it didn't require much UI rework after all. The only thing that I haven't managed to solve yet is how to keep the Drop prompt while carrying an item, right now it's the only thing left in PlayerInteractionComponent._process():

func _process(_delta):
    # HACK: Restores the drop prompt while carrying items
    if is_carrying:
        started_carrying.emit(carried_object)

Part of the UI update in my branch now also happens in PickupComponent instead of (directly) in PlayerInteractionComponent. Wieldables UI is now updated there whenever ammo for current wieldable is picked up:

# Update wieldable UI if we have picked up ammo for current wieldable
# TODO: Replace with a better solution
if _player_interaction_component.is_wielding:
    if "reload_amount" in slot_data.inventory_item and _player_interaction_component.equipped_wieldable_item.ammo_item_name == slot_data.inventory_item.name:
        _player_interaction_component.equipped_wieldable_item.update_wieldable_data(_player_interaction_component)

Not sure what a "better" solution would be in this case. It could be that the component emits a signal that the UI picks up, but at the moment PlayerInteractionComponent is needed anyway at some point of the process, as it holds the necessary information about the player's current state.