Request - Getters/Setters in interactable_cooldown_per_agent (Scene Graph)

interactable_duration has Getters and Setters

 # Returns an agent’s remaining duration, in seconds, for interaction. Fails if the agent is not interacting with this component.Returns the same value when called multiple times within a transaction.
        GetRemainingInteractDurationForAgent<final><native><public>(Agent:agent)<reads><decides>:float

        # Sets an agent’s remaining duration, in seconds, for interaction. Fails if the agent is not interacting with this component.
        SetRemainingInteractDurationForAgent<final><native><public>(Agent:agent, RemainingDuration:float)<transacts>:void

but interactable_cooldown_per_agent doesn’t have any getters and setters and the variable for “RemainingDuration” is private so you can’t manipulate without some Setter function :confused:

You should try basic_interactable_component instead of :slight_smile:

UPDATE : You should wait a little bit before using them…

1 Like

You got me wrong I use basic_interactable_component but cooldownperagent isn’t available to modify at all from verse

interactable_cooldown_per_agent is a configuration class for the basic_interactable_component, and is related to each player having its own individual cooldown after interacting with this component. There is other interactable_cooldown configuration class, that is a globally shared cooldown across all players.

If the component has the interactable_cooldown_per_agent set up (on CooldownPerAgent field):

  • Each player will have it’s own individual interaction time (ex. PlayerA interacts, and will be on cooldown for X time, disallowing interaction for that PlayerA, but, PlayerB can still interact while PlayerA is on cooldown.)

If the component does not have interactable_cooldown_per_agent set up (CooldownPerAgent set as false/empty optional):

  • If component has a interactable_cooldown, will use that cooldown, shared across all the players (ex. PlayerA interacts, and all players will not be able to interact until the cooldown expires.)
  • If component does not have a interactable_cooldown, the interaction will have no cooldown at all before allowing players to interacting again at any time they want.

The interactable_cooldown option holds the data for that shared cooldown time. This includes:

  • Duration → Defines the cooldown time duration, in seconds. You can update this value using set Duration = MyNewDuration any time you want.
  • Remaining Duration → If a cooldown is currently active, this will be the value in seconds of how much time until the cooldown expires (aka allowing to interact again)
  • ExpiredEvent → An listenable event that you can subscribe or await, this will be signaled every time that a cooldown time expires (when it starts allowing interactions again)

The interactable_cooldown_per_agent option is very similar to the one above, but it has extra per-player states so you can read the current cooldown state/times for each player:

  • Duration → Same thing, the cooldown time duration, in seconds. You can update this value using set Duration = MyNewDuration any time you want.
  • RemainingDuration → Same thing, it holds the value in second of how much time until cooldown expiring. The difference is, this time it has per-player information, since on this option each player can have a different cooldown active, not being the same value shared across everyone.
  • ExpiredEvent → Same thing, but this passes the player which the cooldown was expired.

The function you mentioned (GetRemainingCooldownDurationAffectingAgent(Agent)) is nothing more than a ease-usage for querying the data from these two possible configuration options on the interactable_component, what it does is basically this:

GetRemainingCooldownDurationAffectingAgent(Agent:agent):float =
    if (PerAgentCooldownInfo := BasicInteractibleComponent.CooldownPerAgent?):
        if (PlayerCooldown := PerAgentCooldownInfo.RemainingDuration[Agent]):
            return PlayerCooldown
        else:
            return 0.0
    else if (SharedCooldownInfo := BasicInteractibleComponent.Cooldown?):
        return SharedCooldown.RemainingDuration
    else:
        return 0.0

Note that you can even make your own cooldown logic, by using theCanInteract function exposed, overriding it and adding your own interaction condition logic (such as custom cooldowns, gameplay state based activation, player score verification or any other thing you may want!)

my_custom_interactable_component := class(basic_interactable_component) {
    var PlayersAllowedToInteract : []agent = array{}

    AllowPlayerToInteract(Agent:agent):void =
        option:
            not PlayersAllowedToInteract[Agent]
            set PlayersAllowedToInteract += array{Agent}

    DisallowPlayerToInteract(Agent:agent):void =
        option:
            PlayerIndex := PlayersAllowedToInteract.Find[Agent]
            NewPlayersAllowed := PlayersAllowedToInteract.RemoveElement[PlayerIndex]
            set PlayersAllowedToInteract = NewPlayersAllowed

    CanInteract<override>(Agent:agent)<reads><decides>:void =
        PlayersAllowedToInteract.Find[Agent]
}

On this example above I wrote a simple “permission list”, where players on it are allowed to interact, and players not on it can’t interact at all. But as I mentioned, you can make more complex setups, including variable queries, player states and so on… Imagine stuff such as allowing interaction only if player is currently crouching (checking fort_character data) for example…


So, what you are requesting is already possible by using these options mentioned above… Are you trying to implement something specific in your game? We can help you if you have any questions on usage, such as giving examples or ideas for some gameplay mechanic…

2 Likes

In additional info of @Sprintermax who give the best answer

Used to set a cooldown per agent when interacted.

interactable_cooldown_per_agent<native><public> := class<concrete>:
    @editable
    # The duration in seconds after a successful interaction, before the interacting agent can initiate a subsequent interaction.
    # This is only used if the duration is greater than 0.0. Modifying this does not affect any RemainingPerAgentCooldownDuration.
    # This property gives other agents time to interact, when there is a limited number of Simultaneous Interactors.
    var Duration<native><public>:float = external {}

    # The cooldown remaining, in seconds, before a particular agent is able to initiate an interaction on this component.
    var<private> RemainingDuration<native><public>:[agent]float = external {}

    # Event which fires when the per agent cooldown expires. Sends the agent which was previously affected by the cooldown.
    ExpiredEvent<native><public>:listenable(agent) = external {}
1 Like

Thanks for the explanation. What you wrote is enough for me, I wasn’t aware of the CanInteract function existance

1 Like