Forum rules - please read before posting.
Tech questions during the weekend? Drop in on the community Discord channel!

Copying Dialogue from Play Speech Action

Hey all,

Bit of an ambiguous title here! In my game I need a system that tracks conversations the player has with different NPCs. Amazingly I have actually managed to get this working thanks to how awesome AC is and how powerful it is for non-programmers like myself!

Simply what I am doing is I have a script for each NPC that stores various Strings (NPC name, Relationship to Victim, Motive, Alibi and Conversation History). I then have a Menu for a Tablet that the Player uses to access the above info on each NPC that they have met/interviewed - so when NPC01's picture is clicked in the tablet I run an action that will transfer the strings in the custom script I made, attached to NPC01, and it will transfer these values to the relevant Global Variables (because the Tablet menu is reading the AC variables in order to correctly display the information required).

I've even managed to set it up so that with the Conversation History any new String gets added to the existing string (so it retains the previous info) rather than overwriting it - otherwise it would only show the last conversation string that I enter as opposed to all of them together. Again I'm absolutely amazed that I've managed to implement this, yes it took a custom script (and also a custom Remember script to ensure that the data collected is saved) however even after 2-3 years of using AC I'm still so amazed at how amazing this asset is! So thanks again Chris!

Now to the specific problem, the way I add to the Conversation History is that I have to type down the string into a String GlobalVariable (different variable to the one that is read in the Tablet menu by the way) - this works perfectly for my testing to prove everything works however when it comes to implementation in game I'll need to add all the dialogue between the player and a particular NPC. The only way I know how is to, after each Dialogue: Play Speech action I will have to add a new action to Set: Global Variable and then copy and paste the dialogue from the Play Speech into the Set: Global Variable action and then save that into the Conversation History script.

The act of setting the new value of the variable and then saving it in the script at each point of dialogue is simply something I'll have to do however if I later need to change the specific dialogue then I'll have to make sure that I also update the text that is in the Set Variable action too - it seems a recipe for disaster as something will no doubt be missed. So is there a way to set the value of a String Global Variable to be the same as the text in the Dialogue: Play Speech action so that I'm not relying on myself copying and pasting the text from the Play Speech to the Set Variable action each time (and potentially either making a mistake during the copy and paste or not updating following any future dialogue changes)?

Perhaps I'm going about this all wrong and there is a much better way however any guidance on how to implement the above myself (or a better method) would be greatly appreciated.

Thanks again,
Mike.

Comments

  • Yes, you can largely automate this through use of custom events.

    Custom events are a way of running your own code when AC performs common tasks, such as when a character speaks in the tutorial above.

    You can use the above's OnStartSpeech event to keep track of speech, since it fires whenever a speech line is played.

    What would be more tricky, however, is having it so that your custom script is able to add the speech to the correct Variable - since the event is fired for individual speech lines. You could consider using the OnStartConversation event to, in effect, "begin recording" these speech lines.

    Unfortunately, there's no equivalent "OnEndConversation" event - since when a Conversation ends exactly isn't so easy to determine. You can, however, hook into the OnEnterGameState to detect when normal gameplay has resumed.

    This won't be the finished script, but it should demonstrate the principles:

    http://pasteall.org/1506431/csharp

    For more on custom events, see the Manual's "Custom events" chapter.

  • @ChrisIceBox

    Once again just a massive thank you for your amazing help and support on here! I tested out the provided script, it seemed to work for conversations however if I played dialogue outside of a conversation then it wouldn't 'record' the speech (so the OnConversation seemed to work but not the OnStartSpeech).

    I fought the urge to immediately post a response of 'The code provided isn't working as required' because that would be a dick move considering how damn helpful it was that you provided the code in the first place (and so quickly). So instead, armed with my very limited programming knowledge, I tried to figure out how the code provided worked which lead me down a rabbit hole and finally ending up at the ActionSpeech script itself. I've now modified that script so that when I use the Dialogue:Play Speech action I can tick a bool to Log the conversation or not as well as specify a gameobject to send a specific message to (in this case I link the NPC whereby I have the custom script that I mentioned in my opening post).

    So firstly just a huge thanks again for your help, the fact I've managed to create the first script (along with a new remember script) and amend the ActionSpeech script is entirely down to the fantastic tutorial section on the site as well as your help and support on this discussion.

    I have made a backup copy of the ActionSpeech script with my amendments and saved it outside my project because I'm certain that any update to AC will overwrite this script if it detects the changes (so I'll have to manually update the script again with my changes however I've clearly marked each change with notes so it'll be easy to do). What are your thoughts on this workflow? My first thought is that editing/amending AC scripts is a big no no however doing so in this situation seems to make the most sense. Presume as long as I'm only adding and not deleting anything then it's fine?

    Huge thanks again,
    Mike.

  • it seemed to work for conversations however if I played dialogue outside of a conversation then it wouldn't 'record' the speech

    That was intentional, as given your first post I thought that was what you were after. To record all speech - and not just those in Conversations - you only need the OnStartSpeech event without any checks:

    http://pasteall.org/1508482/csharp

    My first thought is that editing/amending AC scripts is a big no no however doing so in this situation seems to make the most sense.

    The "proper" procedure for making custom changes to an AC Action would be to duplicate the script, rename both it's filename, class name, and display name. This way, you can call upon Dialogue: Play speech (custom) instead of the default speech Action - and not have to worry about forgetting to not import over it when updating AC.

    The Dialogue: Play speech Action is a little more complicated, however, because the Speech Manager searches your project for instances of this specific Action type when gathering up game text. To make changes to this, then, you'd want to have your custom Action as a subclass of ActionSpeech, rather than Action.

    This way, it'll be picked up by the Speech Manager - and you only need to re-write the functions you override.

  • My apologies, in my limited knowledge I assumed that the OnStartConversation() was recording speech in conversations and the OnStartSpeech() recorded all speech - I now see the check you refer to in the OnStartSpeech() that was made in the first pasteall which ensures only speech in conversations are made. So obvious now!

    As for the custom Play speech action this actually does seem like the best solution - just thinking about when AC updates, whilst re-updating the ActionSpeech script wouldn't be a nuisance what could/would be a pain would be the fact that I believe I'd have to go through all the actions whereby I previously setup the dialogue action to record speech and I would have to re-enter all the additional info (so whether the new bool to log the conversation or not is true or false and then also 'relinking' the NPC gameobject where the conversation will be saved to).

    Thankfully I've not implemented anything yet (still only tested functionality) so I'll definitely do as you recommend and create a custom action as a subclass of ActionSpeech with the new functionality I require.

    Thanks yet again!

  • Sorry Chris, me again! I've looked into the custom action as a subclass of ActionSpeech instead of Action. I initially just kept the custom script I have and changed the subclass from Action to ActionSpeech however this queried a few methods whereby it asked to confirm if I was intending to hide inherited member and to fix I should specify the 'new' keyword.

    So I have done this to remove any potential errors and the custom action works fine however I'm guessing that this is the wrong way to do this - I presume the best way would be to start with a copy of the ActionTemplate and then change the subclass to ActionSpeech and then only add the extra things I'm trying to do into that - however I'm struggling, some of my code is inside the StartSpeech method of ActionSpeech so is there a way that I can run my new custom action by specifying what small bits of custom code to add to the main ActionSpeech code or do I need to do what I did originally and simply ensure all the code in ActionSpeech is replicated in my custom action to ensure it works correctly?

    Sorry to be a pain, I've read through the Manual, tutorials and this forum but can't see anything relevant to this specific situation.

  • I don't know exactly what changes you're making, or what you're overriding, but if adding "new" does the job, I wouldn't worry about it.

    If any of the functions in the original ActionSpeech require being made virtual, so that you can override them with the 'override' keyword, let me know and I'll amend.

  • Thanks Chris.....I think I'm fine. I've removed any methods in my custom action that were unchanged from the original PlaySpeech action, any methods that were changed I've kept them in full.

    So to confirm my understanding - if in my custom action, with ActionSpeech subclass, if I kept it blank then it would essentially run the entire ActionSpeech code and it would be just like the Dialogue:Play Speech action - however if I wanted to ammend what was shown on the GUI then in my custom action I would copy the ShowGUI method into my custom action, add any additional code to show the additional info that I want and now when run the ActionSpeech code will still be run but the ShowGUI method from my custom action will be used instead of the one in the ActionSpeech script?

    So quick summary the only places where I added code in the original ActionSpeech script was inside the ShowGUI method and the StartSpeech method (and obviously declaring a few custom variables) and so my new custom action only has the full amended ShowGUI and StartSpeech methods and new variables with nothing else (none of the variables in ActionSpeech and not even the Run float).

    Sorry if I have any terminology wrong however hopefully I've explained myself well enough - everything works so I believe my understanding is correct however for peace of mind I'd obviously like to confirm my understanding.

    Thanks again for your help.

  • Yes, that sounds fine to me.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.