Search Unity

Feedback Please rate my approach to an interaction/scripting system.

Discussion in 'General Discussion' started by mochiponzu, Feb 22, 2020.

  1. mochiponzu

    mochiponzu

    Joined:
    Mar 24, 2019
    Posts:
    10
    I'm working on a game that's not dissimilar to a point and click and adventure. So I need a system that, broadly speaking, looks for certain events (such as the player activating a trigger by stepping into it, or a flag being set) and then executes commands like sending an NPC to a certain spot, playing an animation, a sound file or dialogue, setting other flags and so on. The same system should also be used for cutscenes, that is a series of events (animations, dialogue) that use the characters in the scene by giving them simple commands. Basically, pulling a lever is nothing but a mini-cutscene, so to speak.

    My idea is to create three classes that will handle all this.
    Firstly, a "script event" class that inherits from scriptable object (and possibly some subclasses that inherit from this one). Each instance of this class holds exactly one condition (which can be to wait a certain time, or wait for a trigger or flag, or nothing at all (executes automatically)) and one command. It has fields for actors in the scene, items or other things that can be used for these commands.

    Secondly, a script class that inherits from scriptable object as well. This one is basically just an array of the above class, since it will have a public array of the type script event that I can then populate in the inspector. A script could be used to lay out what happens in a cutscene, or what happens when the player walks to a certain spot, or when they use an item on another item and so on.

    Lastly, a script reader class that will inherit from MonoBehaviour and will be placed into the scene. This class will have a field for a script and go through it, that is go through the above mentioned array, look at the individual script events, and wait and check for each condition to be met, and then execute the command specified in that script event and move on to the next script event. Since the above two classes are "scriptable objects" they won't have any Update methods by themselves, but instead rely on the script reader to parse through them.

    I've implemented my ideas on a basic level, but I would like to hear your thoughts on how extendible you think this is, what could be improved or what troubles I might run into. (The further I go with this system, the harder it will be to make changes later.) This approach would let me use the inspector to do a lot of things and basically put scripts together in a drag and drop manner. I could also extend it by creating different subclasses of the "script event" class to handle other, more specific things that might come up later.
    One downside is, that I would have to create a new scriptable object instance of "script event" for every single command. So there could easily be hundreds of these for each scene of the game. I could use a folder structure and naming system to keep them organized, but in the script class (the one that has the array), I can still only put them in one by one. I'm afraid of things becoming very confusing with larger scenes, since different scripts would have to play off of each other.

    I hope I've conveyed my ideas clearly enough for you to have an idea about whether they might work or not. If you have any radically different ideas for these type of systems, I would like to hear about it as well! My ideas are just what I've come up with and I probably haven't thought some things through, so I want to avoid that "If only I'd known that earlier!" moment.
     
  2. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,697
    Hi,

    This should be in the Scripting section. You'll get much better feedback there.
     
  3. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,571
    In my opinion, you're seriously overthinking this. There's no need for a page of analysis, arguments, if you're implementing something that takes 3 classes total. Just write it and see if it works and modify if it doesn't.

    Additionally, you don't really need a system that LOOKS for certain event or SENDS an NPC somewhere. You can implement things this way, but don't have to. What's more, a system that is extensible is going to require more development time, and will be more complex than a system that is not extensible. Unless you're writing an asset store package or a toolkit, it is desirable to forego extensibility and only add features when they're needed. That is if your goal is to ship the game as fast as possible.

    NPC and cutscenes can check for conditions themselves without some sort of director driving them.
    A great deal of functionality can be implemented by loosely coupling basic scripts to AnimatorController. For example, a lever could set a flag on animator, and that would open a door. Neither door nor lever in this case would know about some sort of external condition. What is desirable is to have some sort of global named variable array which can be accessed by objects. This way, a cutscene player can poll that storage itself and see if a variable has been set.

    Basically, the way I see it, you're likely being distracted by "amazingly interesting problem(tm)" from actually implementing gameplay. Try to implement simplest possible solution and roll out "a system", when it is required.

    However, that's simply my opinion.
     
  4. mochiponzu

    mochiponzu

    Joined:
    Mar 24, 2019
    Posts:
    10
    neginfinity thanks for your answer.
    I was thinking so much about a system or extendibility because the game is supposed to use these things a lot, and I want it to be as easy as possible to create and add more dialogue or cutscenes. I fear that if I used the simplest approach that first came to mind, it would not be structured or streamlined well enough and with more and more scenes and triggers added, I'd eventually lose track of what is happening where.
    Maybe I didn't make this clear enough in the initial post, but the system is tied to gameplay in the sense that solving puzzles can trigger events in the scene, affecting the states of things. So it's not simply a scene that plays from begining to end, but several interlinked scripts. I hope that if I put in more thought right now, it will pay off in the long run, by not becoming too messy.

    Your idea of using an animator sounds great, because it can be used to visualize, which might be of help when things get more complicated. I'll keep that in mind and will try to implement it.
     
  5. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,571
    My belief is that it is a good idea to adhere to principles of KISS, YAGNI, and Murphy's Law.

    Basically, don't' implement things you don't need, keep everythin as simple as possible, and at the same time try to prepare for future bugs.At the same time features are added when needed. Foregoing those principles increases development cost.

    With this kind of philosophy in mind, simplest approach that first came to mind may actually be a correct one.

    However, there are people who think differently.

    -------

    In your case I'd try to analyze scenes you're going to implement and see if overencompassing "system" is actually needed to make them happen