Search Unity

Is this a reasonable way to approach triggering game logic in cutscenes?

Discussion in 'Scripting' started by Sendatsu_Yoshimitsu, Oct 5, 2019.

  1. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    673
    I have a really simple dialogue system I implemented with Ink ( https://www.inklestudios.com/ink/ ), it works great for displaying and branching text but I'd like to be able to animate, move, and otherwise command characters, props, and the cinematic camera during dialogues. Every line of dialogue in Ink comes with an associated string that is essentially a comment- the writer can dump whatever they want in it, and it's kept with the line of dialogue but never displayed.

    What I've been doing is using the comment text to insert commands for a really crummy homemade scripting language: given a string of text, it checks if the first word matches some CommandType enum, and if it does, it passes the string to a scripting interpreter which parses the string. It's very crude, every command is essentially some variant of "Hmm, this is a MoveTo command, that means it should have two more words, each corresponding to a prop or actor in the scene. If I can find two matching objects, I'll tell the first one to move to the second one- otherwise I'll fail out."

    It works, but it feels really schlocky, especially since the lion's share of my logic relies on parsing and interpreting strings. Is there a better, simpler solution I could be considering here, or is my best avenue to clean this up simply reading up on creating scripting languages, and refining what I already have to follow best practices?
     
  2. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    4,645
    Well, I personally would go the other way around and utilize the Timeline since other parts of the system can be called from there. But I understand you invested into the ink-based solution and it may not be feasible to change that.
    Well, the other route you can take is what the Dialogue System took and I myself played around with it myself: Lua interpreter.
    You can create a library of Lua commands and you can bind C# commands to fire through them. Then in the string which you're parsing just call the Lua interpreter. If nothing more, a proper interpreter will be part of your system which is generic enough to handle anything as long as you throw the backend systems behind it.
    There are a couple of great Lua solutions for Unity.
    Moonsharp is fairly supported: https://github.com/moonsharp-devs/moonsharp
     
  3. Sendatsu_Yoshimitsu

    Sendatsu_Yoshimitsu

    Joined:
    May 19, 2014
    Posts:
    673
    Oh hey, that seems like a much better idea! (The main reason I don't use Timeline is out of workflow considerations: we have a lot of dialogue but minimal cinematography, so we chose to go with a writer- and data-centered workflow and try to keep it as uncoupled from Unity as possible.)

    The only potential hiccup I could see is performance- assuming my quick glance at the documentation is right, binding C# commands will generally look like this, right?

    Code (CSharp):
    1. private static void Move(string moverID, string targetID)
    2. {
    3.     //move mover to target
    4. }
    5.  
    6. public void ExecuteScriptingComamnd(string scriptingString)
    7. {
    8.     Script script = new Script();
    9.  
    10.     //for each C# function we want to access from plaintext:
    11.     script.Globals["Move"] = (Func<string, string>)Move;
    12.  
    13.     //Once all functions have been registered
    14.     script.DoString(scriptingString);
    15. }
    16.  
    17. public void ControlLoop()
    18. {
    19.     string exampleCommand = @"Move(Bob,door)";
    20.     ExecuteScriptingCommand(exampleCommand);
    21. }
    We have around 20 functions we regularly access from cutscenes, so that means that every line of dialogue with scripting (which is most of them) would create a new Script object and bind twenty functions to it- could you see that being any kind of performance concern, or is MoonSharp efficient enough that it's not a big deal?
     
unityunity