# 📦 KairoEngine.StorySystem v0.2.0 The Story System uses the Ink Language and runtime to navigate through a story written in a plain text file. This package contains the Story Module that receives an ink story and runs it. The story can show lines and branches, execute functions in unity and wait for events. Unity also has an API for navigating, getting and setting variables in the story. ### 🛑Required packages - `KairoEngine.Core` - `KairoEngine.UI` - `Ink` - `UniRX` - `TextMeshPro` - `Sirenix` ### 📄Namespaces - `KairoEngine.StorySystem` - `KairoEngine.StorySystem.UI` - ``KairoEngine.StorySystem.EditorTests`` ### 📙Modules - **Story Module** – Loads a story configuration, instantiates a story controller and starts the story playback. ### 🔷Components - `StoryViewUI` – A generic UI for showing text and buttons based on story events. - `StoryButton` – A button used in the Story View UI - ``StoryText`` – A text object used in the Story View UI ### ✔Getting Started To get started using the Story module, first add it to a game config and add an installer prefab to a scene. Then install [Inky](), the Ink editor. Create a new Ink story, save the file and add it to the Unity project. Unity will generate a JSON file from the Ink file then add it the story module configuration. A simple example Ink story: ``` Once upon a time... * There was a choice. * There was another choice. - And they lived happily ever after.     -> END ``` When this story is run on Unity after been loaded with the story module, it will read the first line and send it as an event to the game. Then it will read all choices and send them as a single event to the game. The story system will wait for another event containing the chosen path. The system will then send an event containing the last line of text in the story and then will stop. The story system publishes events containing ``StoryStepData`` that other scripts can subscribe to. This object contains data about that passage of the story. It can be a line of text, a list of choices or a integer for the path that has been selected. When the Ink story runs, lines and branches will be sent as events imidiatly in order. Wait functions can delay that process. Once a branch has been reached, the story will wait for an event to be sent back containing the selected path. Below, in the Unity Functions section there are instructions on how to send and receive story events with code examples. ### 🧰Ink Functions Use these functions in an Ink document to execute things in Unity. Each function has a usage pattern and the actual function that needs to go somewhere inside the Ink document. ##### Wait Make the story wait for a certain amount of time. In the Ink story file, use ``~Wait(time)`` anywhere in the story to make unity wait the amout of time before continuing the story. ```javascript // Example Usage Something happens ~ Wait(3000) After three seconds another thing happens ``` Add the functions below for declaring a external function to Ink and a fallback function to make it work in the Inky editor ```javascript EXTERNAL WaitForTime(time) === function Wait(time) === ~WaitForTime(time) <> (Wait {time} ms) === function WaitForTime(time) === ~x = "" ``` ##### Enable / Disable GameObject Enable and disable GameObjects. In Ink, use ``~Enable("StoryGameObjectName")`` or ``~ Disable("StoryGameObjectName")``. Add prefabs for the GameObjects used in the story to the list on the Story Module config. ```javascript // Show a menu in the game and close it after the choice is made ~ Enable("MainMenuUI") Main Menu + [Start Game] ~ Disable("MainMenuUI") -> StartGame + [End Game] ~ Disable("MainMenuUI") -> END ``` Add the function below anywhere on the ink document: ```javascript EXTERNAL Enable(name) EXTERNAL Disable(name) === function Enable(name) === > Enable {name} === function Disable(name) === > Disable {name} ``` ##### Wait for Event ##### Trigger Events Triggers a ``GenericEvent`` in unity. Pass in a string containing the name of the event to be triggered. Example: ```javascript ~ TriggerEvent("MyCustomEvent") EXTERNAL TriggerEvent(name) === function TriggerEvent(name) === > Trigger event "{name}" ``` ##### Change Scene ##### Control Slideshow ##### Set Camera ##### PlaySFX ##### Play Soudtrack ### 🧰Unity Functions These are functions used in Unity to change and navigate a Ink story. Also there are helper function for doing various things like observers and events. ##### Go to Story Knot ##### Get Variable ##### Set Variable ##### Receive Story Events To receive story events, simply subscribe to events with the story name and a function. ```csharp EventManager.broadcast.StartListening(storyName, OnStoryStep); ``` The function for these events needs to receive story step data, for example: ```csharp void OnStoryStepData(StoryStepData storyStep) { Debug.Log($"> {storyStep.text}"); } ``` Don't forget to stop listening for events when the script is done. For example, using a monobehaviour derived class: ```csharp void OnDisable() { EventManager.broadcast.StopListening(storyName, OnStoryStep); } ``` ##### Send Story Events When the story has reached a branch, it will wait ultil it receives an event containing the selected path. ```csharp int path = 0; StoryStepData storyStep = new StoryStepData(StoryStepType.Path, text, null, null, path) EventManager.broadcast.Trigger(storyName, storyStep ) ``` ##### Story Observer Instead of declaring delegates using events, it's possible to subscribe to story steps using observers: ```csharp CompositeDisposable composite = new CompositeDisposable(); // Subscribe to the custom observer // Other UniRX functions can be chained here StoryController.Lines().Subscribe(storyStep => { Debug.Log(storyStep.text); // Stop the observer composite.Dispose() }).AddTo(composite); ``` The Story Controller Lines observer requires the ``kairoEngine.StorySystem`` namespace. ### 📄Changelog ##### v0.2.0 - Upgraded GameModule system ### 🎈Back Log - [ ] Support for multiple stories - [ ] More tests