Hello, HappyDeadPictures,
Don’t worry, you are doing it right up until this point and it is correct to use a ray cast. Remember that when you send an event through an interface, for example on a raycast hit, the interface message will be sent immediately, which is what you want.
On the receiving blueprint, on the other hand, you would fire your implementation of a “countdown” event, instead of your “unlock” event directly. When your countdown finishes, you fire the unlock.
Although it sounds logical to use a timeline (on message received play the timeline, on timeline finish fire your unlock event) I wouldn’t do it this way. The reason is that if you stop your raycast, the timeline will keep running and eventually fire the unlock because nothing has told it to stop. So you would need a second message that somehow gets send when you stop interacting, so that you can stop the timeline.
What I would do instead, is have a boolean on your object named isBeingInteracted, defaulted to false. Also, a float named timeToInteract, defaulted to whatever time limit you want, and a float named timeInteracted, defaulted to 0.
On your interactable actor, on event tick, check if the boolean is true or false. If it is true, add the delta time to timeInteracted, and compare if it is greater or equal than timeToInteract. If it is, fire your unlock event. If it isn’t, do nothing. On the other hand, if the first boolean check is false, set timeInteracted to 0 (thus resetting it).
And here is the trick. After you have run through the nodes that I described, you want to set isBeingInteracted to false. You do that after testing it, every tick. You might plug a sequence node from the event tick and the first execution output fires the branch that checks the boolean, adds the time and eventually fires your event, and the second output just resets isBeingInteracted to false.
And now, when you receive your interface message, what it does is only to set the isBeingInteracted boolean to true.
That way, if you are not interacting (no message is being received), then the blueprint itself will reset that value, and reset its interacted time. If you are interacted, your boolean will be true the moment that you do the check and you will be adding time to your counter.
This way, you don’t need a second event or method to detect the end of the interaction, because if no info is received the blueprint resets itself.
I have used this method and it works for me quite well. There are a lot of ways to do this, some probably better than what I described. Hope it makes sense.
All the best.