Hey there!
Maybe this was asked already but I havent found a solution in the forums.
Like what the title say: Where does player interruptions come from?
And how would I utilize them to interrupt interactions currently carrying out by the player?
What I want to achieve is: I have a door and a chair.
1) While I am on the ground I want the player to walk to door and open it
2) While I am on a chair I want the player standup, then walk to door and open it
I can setup these as seperate interactions but the problem is that 1st is interuptable by default. The 2nd is not.
How would I achieve that also the 2nd is interuptable (when I click somewhere else during my walk to the door)?
Thanks in advance for your help!
Edit: Oh, and I saw already that Character: Move along path would cancel the current interaction. But where would I call that or its c# pendant?
It looks like you're new here. If you want to get involved, click one of these buttons!
Comments
Welcome to the community, @DctrElectro.
The "pending interaction" can be cancelled by calling the PlayerInteraction class's StopMovingToHotspot function:
Calling this function also triggers the OnHotspotStopMovingTo custom event, which can be hooked into if you need to handle anything else as a result of a particular Hotspot interaction being cancelled.
Thanks Chris, I am aware of that but it doesnt solve my described problem.
But maybe I thought it from the wrong end.
I am currently trying to solve it with a Custom-Action and two hotspot actions.
1) Walk-To-Marker -> Open-Door action list (which is disabled)
2) Do Nothing -> Custom-Action action list (which is enabled)
In my Custom-Action action list I check if player is on ground or on chair and depending of that trigger the first Use-Action (TriggerHotspotAction) of the door so my expectation is that the player walks to the door, which is interruptable.
https://pasteboard.co/fF9t9iYvsST9.png
In my Custom-Action I have trouble to Run the appropiate action, because there are two of them and if I disable the second it doesnt get called.
I run the hotspot this way
hotspot.useButtons[0].isDisabled = false; hotspot.RunUseInteraction(); hotspot.useButtons[0].isDisabled = true;
But then I receive this error as soon as the player reached the door:
NullReferenceException: Object reference not set to an instance of an object AC.PlayerInteraction+<UseObject>d__35.MoveNext () (at Assets/AdventureCreator/Scripts/Controls/PlayerInteraction.cs:1214) UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <3be1a7ff939c43f181c0a10b5a0189ac>:0)
It seems that the button which caused the walk-to gets lost and therefore there is no reference to the marker, am I right?
What would you suggest here? Is there a better way?
Please correct me if I'm misunderstanding the issue, but as I understand things you should be able to rely on a separate Hotspot for the "walk to" Interaction. This would be off-screen and not clickable by the player directly - with the one over the door running the "intermediate" Interaction in your screenshot.
Since this separate Hotspot interaction is only triggered indirectly, it doesn't need to have any of its Interactions disabled. You should then be able to trigger it without needing to enable/re-disable anything either side of it.
Triggering the Hotspot interaction through ActionList may be a little tricky because you'll need to make sure that the game is in "gameplay" at the time. This could feasibly be done by setting the ActionList's When running field to Run In Background, but another way would be to attach a script to it that interacts with the "hidden" Hotspot once the ActionList completes - by way of the OnEndActionList event:
With this approach, you can remove the third Action in your Interaction ActionList and simply run the "Arm chair (Use)" ActionList if the Variable is True.
As an aisde: a totally different approach would be to not rely on the "pending Hotspot interaction" system at all, and instead move the Player through a regular Character: Move to point Action in a separate background ActionList, which gets interrupted upon the player clicking anywhere through script.
Thanks a lot Chris, this brought me on the right track!
And just to get back to the thread title: You wrote
Is there an Event I can listen to which provides that the Player clicked anywhere?
Not for generic clicks - that'd be a case of reading Input.GetMouseButtonDown in an Update loop and checking the conditions at the time, i.e. is the game in "gameplay" mode, and the cursor not over a Menu:
Hey Chris, me again.
I am afraid I dont get how to not rely on the "pending Hotspot interaction" system.
When I chain up the interaction like in the screenshot like you proposed I see no way where the gameplay is not getting blocked without avoiding "Well now I am here" showing instantly.
https://pasteboard.co/MExWoE7uXYvB.png
But if gameplay is blocked the proposed interruption doesn't work and clickabke Hotspots are nor shown.
What am I missing?
All I want to achieve is to send the player on a skippable walkTo towards a hotspot/marker inside an action list and continue actions once he reached it.
If there is no "in-house" solution I am going to hack this into Adventure-Creator.
My idea is to extent the ActionCharPathFind class and switch the running actionlist to backgroundmode during the movement. When the character arrives at the position I switch the actionlist back to pausegameplay.
Is there any drawback of this?
In your example screenshot, the ActionList: Run Action's After running field would be set to Stop so that it doesn't continue to block gameplay.
Naturally, this'll also stop the speech from playing - but you can have ActionList run from this point by passing it as a parameter into the "Walk to (Interaction)" ActionList.
In this ActionList, you're passing the Hotspot as a GameObject parameter. If you create another GameObject parameter (named "ActionList to run"), and an Integer parameter ("Action index"), you can follow up the Character: Move to point Action with a separate ActionList: Run Action that re-runs the original ActionList from Action #2 (the Dialogue: Play speech Action).
To do this, assign the "ActionList to run" parameter, uncheck Run from start?, and assign the "Action index" parameter underneath. This'll cause the original ActionList to resume once the Player has finished moving.
Subclasses of existing Actions can be written and used as replacements by installing them in the Actions Manager, to avoid hacking AC's scripts directly.
However, modifying an ActionList's When running field while it's running will cause issues and should be avoided. AC keeps track of what ActionLists are running and in what manner, so changing this data mid-run will invalidate this data and break things like the ability to skip cutscenes, etc.
Thanks for you suggestion Chris! Now I understand - it sounds quite error prone though, but I'll give it a try.
You are right I could have just created a derived class from the Character:Move to point Action. But from first glance the solution I implemented works as it should.
I am aware of the skip cutscenes part you wrote. So I make sure that every actionlist which use this has skippable off and shouldnt be added to saves. fingers crossed
It was only an alternative suggestion - I'd recommend trying the dummy Hotspot approach I mentioned beforehand, unless I misread the issue.