Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Game Switches for NPCs/Events

Discussion in 'Scripting' started by CatchFires, Jan 17, 2021.

  1. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    EDIT: If you have any reference material that could relate to this, I'm not really sure how to even approach it.

    To get to the point;

    I would like to be able to create in game "events" (These could be people or objects) that change their current Dialogue/Sprite etc depending on the currently active event page and those pages would have conditions.

    I was thinking of having a BaseEvent script, which all events have that determines how many event pages the particular event had and also a refresh method that is called whenever a GameSwitch is toggled.

    Each page would have conditions that need to be met.

    How would I create a game page through script and determine what switches it needs to be active?

    I feel a bit stuck on how to get started on this system.

    I've included a screenshot from RPGMaker VX, I am not looking how to make the GUI for this page, this is more just a visual representation of what I hope to achieve.


    RPGMakereventsystem.png
     
    Last edited: Jan 17, 2021
  2. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Kind of a complicated system it looks like. I've never really used RPGM, and I'm sure a lot of work went into creating their event system. Sorry I don't have any insight on how to build something similar, but I would point out that, if you're struggling with this, there are some frameworks available on the asset store that might suit your needs, for example:

    https://assetstore.unity.com/packages/tools/game-toolkits/rpg-editor-ork-framework-125912
    https://assetstore.unity.com/packages/templates/systems/easy-event-maker-88686
     
  3. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    Hey, I appreciate the links to those assets but I'm more inclined to create my own things.

    Yeah, their event system is great, I'm not looking to make this whole thing, mostly I'm just looking to create Event pages with conditions and how to activate those pages if their conditions are met.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    There are some good Youtube tutorials on making dialog systems, which I believe is what you are calling an "event"

    Keep in mind the word "event" has very specific C# and Unity-context meanings, so continuing to use that word to describe a dialog system or quest system might lead to confusion.
     
  5. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    Hi Kurt, no this is not a dialog system, this is more like a system that could use the dialog system, or other actions.

    Yes, I can see the confusion, I'm familiar with events, I'm not sure what else to call them though but for now an Event that I have in mind would be like;


    if(conditions(page1))
    {
    UseAction(Dialog)
    }


    But, if conditions for page 2 are met, page 1 shouldnt run, only page 2 even if page 1 conditions are met. If that makes sense
     
  6. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Not everyone has used RPG maker, so that tool's lingo isn't going to help you here. I took a brief look at RPGM event pages, and it looks like an overworked system to me. It fulfils the role of if statement, possible collision detection, and even running cinematic moments? correct me if I'm wrong about this.

    I feel you either need a fundamental shift in thinking, or recreate RPGM in unity, and I'm not sure which is better.

    The closest thing that I feel comes close to RPGM event pages is dialogue trees. RPGM event pages seem to be a daisy chain of actions, with exit on failure or finish, which fits nicely with how a dialogue tree functions, although the structure is not gonna be very clean.

    If you are adamant of making a tool like that yourself, I recommend starting with how to make a node editor; A simple one where you can create nodes and link one to another with a line. From that starting point, you can can fill in the nodes with data you want, which your interpreter in the scene will then execute, as RPGM would event pages.
     
  7. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    Hey man, yes you're right it is an overworked system, it's meant to bypass scripting for people to just dive right in, so it kind of covers everything, but it's not the interpreter I'm trying to create it's the conditions.

    I apologize if I'm not making myself clear.
    Like you said the lingo is different so this is probably a bit confusing.

    All I want to do is have a "Page" class that defines conditions and a class that chooses an active "Page" if those conditions are met.

    How would I define conditions in a "Page" class?

    A condition could be a bool or an int value or like the picture, it could be whether or not the player has a certain item in their bag. So I thought using generics to create a Condition<T> class where T could be Condition<Bool> and page could have say two conditions


    Code (CSharp):
    1. public class EventPage
    2. {
    3.     //private Condition<bool> = GameSwitch[1];
    4.     //private Condition<int> = gameVariable[1] > 0
    5. }
    And a Class that has event pages something like


    Code (CSharp):
    1. public class GameEvent
    2. {
    3.    // private EventPage[] eventPage;
    4.  
    5.    // private EventPage activeEventPage;
    6.  
    7.       void OnMapRefresh()
    8.   {
    9.  
    10.      //this would subscribe to a c# event that would ping every time a switch changes
    11.      //Check if switches/variables for event page == true, activeEventPage = eventPage[i]
    12.  
    13.   }
    14.  
    15. }
     
  8. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    Essentially, you are creating a front-end for the data, and that's entirely up to you to decide. You will still need the interpreter in your scene to make sense of the data in the game though.

    If you're asking where this data should be in, ScriptableObjects is something relatively easy to setup and play with in editor scripting, you can have individual scriptable objects as your pages, create and fill them in, and you drag them into each other to form your chain of events, maybe with 2 slots for success and failure. With that, you'll probably need a condition scriptable object, and variable scriptable objects for the condition evaluate.

    This is essentially the nodes before a node editor. I can't recall if scriptable objects is something you can create freely at runtime; in the event it can't be created at runtime, it's not something modders can play with.

    If you want modders to be able to play around with this, serializing to json is an easy option, you'll need to figure out storing the linkages between everything though. If you want to create them at runtime, you might need a runtime editor within the game, instead of editor scripting one into Unity.
     
    CatchFires likes this.
  9. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    Thank you for the reply, I've taken some time to do some reading and I think I am asking the wrong question I was set on the one idea.

    So, I would like to ask;

    What is a good way to implement npcs that can react to your progress or certain things about the player?

    And would I simply script each npc individually I.e

    Code (CSharp):
    1. public class Dave : BaseNPC
    2. {
    3.   //Dave does stuff
    4. }
    I found a post talking about Bethesda's approach using Flags. But I don't entirely understand
     
  10. Laperen

    Laperen

    Joined:
    Feb 1, 2016
    Posts:
    1,065
    I'm not sure about how bethesda does it, although I would assume its all just a bunch of stat checks behind the scenes.

    Take Dungeons And Dragons(DnD) for example; succeeding in a conversation is most of the time a Charisma stat check. The Dungeon Master(DM) decides the threshold value, the player rolls a dice and adds their character's bonuses and drawbacks. If the player's final challenge value is higher than the threshold set by the DM, the player succeeds, otherwise they fail.

    In a videogame like fallout, maybe your selected faction, something you chose to wear, your other alliances, the companion you chose to have you following along, all are things that the npc takes into account to set their threshold, and you use your stats to challenge that threshold. The stat you use might depend on how the conversation is contextualized. Eg: If the context is a arm wrestling match, then it makes sense for the strength stat to be used for the challenge, compared to maybe intimidation with a Size stat if it exists, or just sweet talking with Charisma like DnD.
     
  11. Havyx

    Havyx

    Joined:
    Oct 20, 2020
    Posts:
    140
    This.

    It's rare you will ever be able to apply the workflow of one engine to another.

    This is a good example. In Unity people and objects are not "events".

    The problem is it's a little confusing trying to understand what you want due to the differences in terminology.

    Scriptable Objects
    Scriptable objects act like data containers that can be used to pass data between scenes or scripts. You could use them to create an event template.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "Data", menuName = "SO/Event Template", order = 1)]
    4. public class EventTemplateScriptableObject : ScriptableObject
    5. {
    6.     public int eventID;
    7.  
    8.     public bool condition_01;
    9.     public bool condition_02;
    10.     public bool condition_03;
    11. }
    You could extend this to have scriptable objects for different dialogue types.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "Data", menuName = "SO/Dialogue Template", order = 1)]
    4. public class DialogueTemplateScriptableObject : ScriptableObject
    5. {
    6.     public string[] christmasDialogueOptions;
    7.     public string[] halloweenDialogueOptions;
    8.  
    9. }
    This would allow you to switch between different sets of dialogue.

    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class NPC : MonoBehaviour
    5. {
    6.     public DialogueTemplateScriptableObject dialogueData;
    7.  
    8.     public string[] currentDialogueOptions;
    9.  
    10.     public void SwitchActiveDialogueOptions(string dialogueType)
    11.     {
    12.         // switch the NPC's active dialogue from the christmas dialogue to the halloween dialogue.
    13.     }
    14.  
    15. }
    Some more ideas:


    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "Data", menuName = "SO/Player", order = 1)]
    4. public class PlayerScriptableObject : ScriptableObject
    5. {
    6.     public int headEquipment;
    7.     public int bodyEquipment;
    8.  
    9.     public string faction;
    10.  
    11. }
    Code (CSharp):
    1.  
    2. using UnityEngine;
    3.  
    4. public class NPC : MonoBehaviour
    5. {
    6.     public PlayerScriptableObject playerData;
    7.  
    8.     private void TalkToPlayer()
    9.     {
    10.         if (playerData.faction == "rebels")
    11.         {
    12.             Debug.Log("Player is rebel scum!")
    13.             AttackPlayer();
    14.         }
    15.     }
    16.  
    17.     private void AttackPlayer()
    18.     {
    19.     }
    20.  
    21.  
    22. }
    This isn't to say it's the best way to do it. What you're asking for is quite complex but hopefully that might help to convey one potential way of achieving your goal.
     
  12. JoshWindsor

    JoshWindsor

    Joined:
    Jun 2, 2018
    Posts:
    24
    I used RMXP back in the day and know the system you are talking about. It was pretty cool!

    The way that I would perhaps go about it is create one large ‘gameManager’ or ‘KeyEvent’ script. I’d personally use a scriptable object for this as essentially your just storing a list of bools.

    This would keep track of all significant changes in the world. I.e house burns down. I havnt really made cutscenes before however I assume these kind of triggers could happen within Timelines.

    If a house was going to burn down, once the burntHouse script was triggered, this bool could then be stored in the KeyEvents and involved Npcs could be programmed to reacte accordingly to that event?

    Another quick thought having just seen the post above is the use of Enums and switches. This coukd be used to change dialogue / cause different behaviour as frequently as you wanted. Lines of dialogue would need to be written inside the script though.
     
    seejayjames likes this.
  13. seejayjames

    seejayjames

    Joined:
    Jan 28, 2013
    Posts:
    685
    I've used a bit of RPGMaker as well. The event system UI is pretty slick actually, once you figure everything out.
    To translate to Unity just think about what those switches are: switches are bools, vars are ints. These are "global" so are shared among every Actor. This can be done with one main script as mentioned. You can also mark variables as static, so there's only one of them, and they can be accessed everywhere without getting a reference to that main script. I'd probably do that.

    For the "pages", well, those are just a series of events that occur if certain conditions are met. This would be some kind of if/else structure that is called up when an event happens (like running into an NPC). So, if that collision/meeting happens, check the status of X, Y, Z switches and/or vars, and act accordingly. I wouldn't think about "pages" per se, that's more of a UI reference with RPGMaker. Rather, you have the "pages" within the if/else structures, which can check for any condition you want. I would also have the if/else be very bare-bones, like:

    Code (CSharp):
    1. if (condition1) {
    2.     condition1Method();
    3. } else if (condition2) {
    4.     condition2Method();
    5. } etc.
    This way, all the resulting actions happen in the methods, which essentially are your "Pages".
     
    JoshWindsor likes this.
  14. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    @JoshWindsor

    That was the route I was originally thinking of going down, I have a main script that holds PlayerData and the Database I have such as items or opponents.
    So making an NPC or entity react to you could be as a simple as "If(Main.PlayerData.HasItem(){ // Do stuff;}"

    But then I thought, what if those entities had a different state such as maybe their sprite is permanently changed or they now moved a different way, I'd need to be able to save that state so the next time you load the game they'd be in the same state or I'd need to be able to set their state dynamically as the game progresses.

    Then I thought but saving individual npcs and their states could end up being pretty hectic, if they had different states depending on what switches(flags) had been toggled, I could save those flags as true/false so on load up, the entities would automatically enter their correct state, or I could ping them with c# events (OnMapRefresh event in the script below) so every time a flag was changed, any NPC that was using that particular flag could be updated.

    Code (CSharp):
    1. using System;
    2. using UnityEngine;
    3.  
    4.  
    5. public static class Main
    6. {
    7.  
    8.     public static PlayerData PlayerData { get; private set; } = new PlayerData();
    9.  
    10.     public static Database Database { get; private set; } = new Database();
    11.  
    12.     public static DialogueWindow DialogueWindow { get; private set; } = GameObject.Instantiate(Resources.Load<DialogueWindow>("Prefabs/Dialogue/DialogueCanvas"));
    13.  
    14.     public static bool DatabaseLoaded { get; private set; } = false;
    15.  
    16.  
    17.     public static event EventHandler OnMapRefresh;
    18.  
    19.     static Main() => Main.Initialize();
    20.  
    21.  
    22.  
    23.     static void Initialize()
    24.     {
    25.         GameObject.DontDestroyOnLoad(DialogueWindow);
    26.         Start();
    27.     }
    28.  
    29.     static void Start()
    30.     {
    31.         Database.BuildDatabase(() => DatabaseLoaded = true);
    32.     }
    33.  
    34.     static void MapRefresh()
    35.     {
    36.         OnMapRefresh?.Invoke(null, EventArgs.Empty);
    37.     }
    38. }
     
    Last edited: Jan 17, 2021
  15. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    @Havyx

    Scriptable objects data is permanent right, like you said, it saves between scenes and things, so if I had them in SO's I could change their state, and it would stay that way?
     
  16. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Changes made to ScriptableObjects are not persisted across play sessions. Think of them more like a static database.
     
  17. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    So I would have to save their SO data and load it up on Play Sessions? That seems like a lot of unnecessary data, thats why I was thinking of doing this "page system" I'd only have to save the flags.

    I mean, I'm not sure how other developers design their systems, I'm kind of just winging it and trying to find a good system.
     
  18. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    I simply would not use ScriptableObjects for data that you expect to change. E.g. part of your saved game system. It's a common misconception that they will somehow help with saved games, and they don't.

    But to store your game's events and triggers it may make sense to use them.
     
  19. Havyx

    Havyx

    Joined:
    Oct 20, 2020
    Posts:
    140
    Yes (and no).

    It's permanent in-editor but not permanent in-build.

    in-editor
    1) some scriptable object integer is set as 5.
    2) you enter play mode and some script interacts with the SO instance and increases the number by 1.
    3) you exit play mode. The scriptable object integer is now 6.

    in-game
    1) some scriptable object integer is set as 5.
    2) player starts the game. Some script interacts with the SO instance and increases the number by 1.
    3) player stops playing.
    4) player starts playing game again. The scriptable object integer is 5.

    One of their benefits is being scene-agnostic. This allows you to cut down on data references that might otherwise need to be shared between scenes with disgusting things like singletons (ok that's a joke but still)

    Additionally, they allow a certain flexibility too in terms of implementation.

    Scenario 01
    In this case "SO/Core/Player" is just an arbitrary path used for organisation. It's the navigation that will appear if you right click in project window.


    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "Data", menuName = "SO/Core/Player", order = 1)]
    4. public class PlayerScriptableObject : ScriptableObject
    5. {
    6.     public int health;
    7.     public int currentWeapon;
    8.     public string somethingElse;
    9. }
    You might have two separate scenes each with their own manager.

    Scene 01
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SceneOneManager : MonoBehaviour
    4. {
    5.     public PlayerScriptableObject playerData;
    6.  
    7.     void Start()
    8.     {
    9.         Debug.Log(playerData.health);
    10.     }
    11. }
    12.  
    Scene 02
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SceneTwoManager : MonoBehaviour
    4. {
    5.     public PlayerScriptableObject playerData;
    6.  
    7.     void Start()
    8.     {
    9.         Debug.Log(playerData.health);
    10.     }
    11. }
    12.  
    In this case the player's health does not need to be passed from one scene to the next using some kind of gameobject or singleton. Scriptable objects are assets that exist in the project itself.

    Also, consider something else.

    Imagine 50 enemies each with their own copy of GenericEnemy.cs

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class GenericEnemy : MonoBehaviour
    4. {
    5.     public int health;
    6.  
    7.     public void TakeDamage(int damageAmount)
    8.     {
    9.         health -= damageAmount;
    10.     }
    11. }
    12.  
    This is more efficient.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class GenericEnemy : MonoBehaviour
    4. {
    5.     public GenericEnemyScriptableObject enemyData;
    6.  
    7.     public void TakeDamage(int damageAmount)
    8.     {
    9.         enemyData.health -= damageAmount;
    10.     }
    11. }
    12.  
    and................

    One more thing you can do is this. Say you want to be able to use scriptable object but you don't yet know what the variables are going to be called or you want to be able to use the same template for multiple different variables.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "Data", menuName = "GenericInt", order = 1)]
    4. public class GenericInt : ScriptableObject
    5. {
    6.     public int value;
    7. }
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class GenericEnemy : MonoBehaviour
    4. {
    5.     public GenericInt playerHealth;
    6.  
    7.     public void Start()
    8.     {
    9.         Debug.Log(playerHealth.value)
    10.     }
    11. }
    12.  
     
  20. Havyx

    Havyx

    Joined:
    Oct 20, 2020
    Posts:
    140
    I disagree. It's fairly common to unpack persistent data into scriptable objects when first loading a game and subsequently having in-game systems accessing that data - the updated SO data is then pulled back out by a persistence data system on a regular basis and when the game is closed.

    Not sure how it could be a misconception when it's Unity that has promoted their use in the way.

    For example:

    Player health is unloaded from persistent data into a scriptable object. Various scripts interact with the the SO and increase/decrease the player's health. Either periodically or when the game closes, the layer SO data is persisted with JSON or some other method.

    I don't think they are a one size fits all solution but they definitely have a use with persistent data and saving game states. You don't have to use them but they can be beneficial in certain situations.
     
    Last edited: Jan 17, 2021
  21. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    Thank you everyone for your input, it really set my thinking into gear and decide how I want to do things.

    I believe for what I want, the pages system was a good thought but I think I can simplify it by giving entities an int for their current "stage". this way either OnMapLoad or OnMapRefresh entities can check which flags they use are true and set their own stage dynamically. And upon interacting with said entities they can respond and act according to the particular stage they are set to.

    Code (CSharp):
    1. public class Dave : BaseNPC, IInteractable
    2. {
    3.        private int currentStage
    4.  
    5.        private void Start()
    6.        {
    7.          Main.OnMapRefresh += SetStage;
    8.        }
    9.  
    10.        private void SetStage()
    11.        {
    12.           if(Main.Flag("Flag1"))
    13.           {
    14.              currentStage = 2;
    15.           }
    16.        
    17.        }
    18.  
    19.       public void OnInteract()
    20.       {
    21.          switch(stage)
    22.          {
    23.             case 1:
    24.             break;
    25.            
    26.             case 2:
    27.             break;
    28.          }
    29.       }
    30. }
    I mean, this is some quickly put together pseudo code, but I think I can work with this quite well.

    Again, thank you for taking the time to help me and of course I am still open for any thoughts you might have, for now, I'm going to dive in.
     
  22. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Fair enough, I can see the benefit of using SOs as inspector-referencable scene-agnostic places to bootstrap data into. What i was referring to was people using SOs as data elements themselves, and instantiating them at runtime via ScriptableObjectUtility.CreateInstance. When used in that way there's no benefit I can fathom of SOs vs plain old C# objects.
     
    Havyx likes this.
  23. Havyx

    Havyx

    Joined:
    Oct 20, 2020
    Posts:
    140
    oh yeah that seems pointless. I thought there might have been something I was overlooking.

    I've only mainly ever seen them used when you have a bunch of settings that never change or using them as an intermediary between different systems to pass data.

    They also provide a pretty nice interface for doing stuff via remote settings like holiday events or "double xp weekend" type of things.

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [CreateAssetMenu(fileName = "Data", menuName = "Example", order = 1)]
    4. public class GenericInt : ScriptableObject
    5. {
    6.     public int xpMultiplier;
    7. }
    Now anything can easily grab the multiplier regardless of scene or scenario. Killing an enemy, completing a level, etc could all use the xpMultipler in their calculations and then when you change it from 1 to 2 it should just work™ across the entire game.

    Code (CSharp):
    1.  
    2. public GenericInt xpMultipler;
    3.  
     
    PraetorBlue likes this.
  24. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    There can be one benefit: if you have an inspector such as Odin Inspector or Advanced Inspector, you can actually manipulate the contents of those transient not-on-disk ScriptableObjects directly from references in the inspector.

    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class MyScriptableObject : ScriptableObject
    4. {
    5.     public int foo;
    6.  
    7.     public string bat;
    8. }
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class Showoff : MonoBehaviour
    4. {
    5.     public MyScriptableObject MySO;
    6.  
    7.     void Start ()
    8.     {
    9.         MySO = ScriptableObject.CreateInstance<MyScriptableObject>();
    10.         MySO.foo = 1234;
    11.         MySO.bat = "Blarg!";
    12.     }
    13. }
    And when running with Advanced Inspector, we have this:

    Screen Shot 2021-01-17 at 5.25.40 PM.png

    It's purty cool actually!
     
    PraetorBlue likes this.
  25. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Can't you do this with any serializable type?
     
  26. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    TIL! Never noticed that before.

    Well, the specific use case I had in mind for runtime SO was not so much the CreateInstance use case but rather the ScriptableObject asset defining something on disk, and when you create a runtime instance of it you just Instantiate<>() it and dirty it up at runtime, wear it out, buff it up or grind it down, etc..

    (I will stipulate that the above use case muddies the intention waters a little bit though.)

    Dang, didn't realize AI could do any old serializable, but you are absolutely correct, it sure does (Adding to the above):

    Code (csharp):
    1. [System.Serializable]
    2. public class MyPOCO
    3. {
    4.     public int foo2;
    5.     public string bat2;
    6. }
    Code (csharp):
    1. // extra lines in Showoff script Start():
    2.         Poco = new MyPOCO();
    3.         Poco.foo2 = 4321;
    4.         Poco.bat2 = "Yaaargh";
    Screen Shot 2021-01-17 at 5.35.53 PM.png

    Additionally, "Gaaargh!"
     
    PraetorBlue likes this.
  27. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    I just checked and unfortunately, without an "advanced" inspector, it is not sufficient to decorate your
    ScriptableObject
    with
    SerializableAttribute
    and get the same ability. The SO instance just stays as a draggable field slot.
     
  28. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    Whoa, mind BLOWN... did not realize you can doubleclick on a non-disk runtime instance of a ScriptableObject field and you open an instance inspector just for that object! Double TIL! This is even without an advanced inspector.

    Screen Shot 2021-01-17 at 6.03.51 PM.png
     
    PraetorBlue likes this.
  29. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    This works with other runtime-created serialised objects as well, e.g. meshes, textures etc.
     
    Kurt-Dekker likes this.
  30. Stardog

    Stardog

    Joined:
    Jun 28, 2010
    Posts:
    1,887
    I would take another look at Bethesda's Quest editor for Elder Scrolls/Fallout. They have different Stages (pages), like you are doing here.

    You might have issues organising this, as far as timing everything. For example, I think RPGMaker (I last used it in 2005...) is very rigid in that the entire game will block you doing stuff when interacting, and actions occur one after the other, with very little overlapping. You will need to control your game's 'mode' carefully, so you can't interact with Dave when he's part-way through a sequence. Your entire game will probably have to go through this system.

    For the Contents, you would use the Command Pattern. Give everything that can happen in your game a dedicated Class (CharacterMoveTo, CameraLookAt, PlayCutscene), just like RPGMaker does. You can even use the hierarchy as a way to create a sequence of commands:
    sequence1.png
     
    CatchFires and Kurt-Dekker like this.
  31. CatchFires

    CatchFires

    Joined:
    Jul 19, 2020
    Posts:
    38
    That command pattern link is a good read, i've read over it a couple times now and I think you're right, I should utilize this.

    I wasn't going to go as rigid as RPGMaker, I only wanted to have a way to set npcs states(pages) depending on certain conditions, but I think implemented right Ill be able to set up some cool scenes. Thank you.


    Edit: Man, the command pattern is awesome. I've already made a couple commands like "SendDialogMessage" and a basic interpreter that is able to read and make use of it. As well as also having a bool to tell if the interpreter IsBusy so it can't be overtaken while in use.

    Honestly, this is really fun lol.
     
    Last edited: Jan 18, 2021