123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using KairoEngine.Core;
- using Ink.Runtime;
- using UniRx;
- namespace KairoEngine.StorySystem
- {
- // Todo: Request events for getting and setting story variables
- [System.Serializable]
- public class StoryController : System.Object
- {
- private TextAsset inkJSONAsset = null;
- private Story story;
- private string name;
- private bool logText = false;
- private bool started = false;
- private int lineInverval = 250;
- public bool wait = false;
-
- private CompositeDisposable disposables = new CompositeDisposable();
- private List<StoryObject> storyObjects;
- public StoryController(TextAsset inkJSONAsset, string storyName, bool logText = false)
- {
- this.inkJSONAsset = inkJSONAsset;
- this.name = storyName;
- this.story = new Story (inkJSONAsset.text);
- this.logText = logText;
- }
- public StoryController(TextAsset inkJSONAsset, string storyName, List<StoryObject> storyObjects, Transform parent = null, bool logText = false, int lineInverval = 250)
- {
- this.inkJSONAsset = inkJSONAsset;
- this.name = storyName;
- this.story = new Story (inkJSONAsset.text);
- this.logText = logText;
- this.lineInverval = lineInverval;
- this.storyObjects = storyObjects;
- foreach (var item in storyObjects)
- {
- item.instance = GameObject.Instantiate(item.prefab, parent);
- item.instance.SetActive(false);
- item.instance.name = item.instance.name.Replace("(Clone)", "");
- }
- }
- public void Start()
- {
- if(started) return;
- started = true;
- GenericEvents.StartListening(name, JumpToPath);
- EventManager.broadcast.StartListening(name, SelectStoryBranch);
- EventManager.broadcast.StartListening(name, PublishStorylineToObservers);
- if(logText) Debug.Log($"Starting {name}");
- story.BindExternalFunction ("WaitForTime", (int time) => { Wait(time); if(logText) Debug.Log($"Waiting {time}"); }, false);
- story.BindExternalFunction ("Enable", (string name) => { EnableGameObject(name); if(logText) Debug.Log($"Enabling {name}"); }, false);
- story.BindExternalFunction ("Disable", (string name) => { DisableGameObject(name); if(logText) Debug.Log($"Disabling {name}"); }, false);
- story.BindExternalFunction ("TriggerEvent", (string name) => { GenericEvents.Trigger(name); if(logText) Debug.Log($"Triggering event {name}"); }, false);
- var storyStream = Observable.Interval(TimeSpan.FromMilliseconds(250))
- //.Where(_ => wait == false)
- .Subscribe(_ => StoryLoop())
- .AddTo(disposables);
- }
- public void Stop()
- {
- GenericEvents.StopListening(name, JumpToPath);
- EventManager.broadcast.StopListening(name, SelectStoryBranch);
- EventManager.broadcast.StopListening(name, PublishStorylineToObservers);
- disposables.Clear();
- started = false;
- if(logText) Debug.Log($"{name} has stoped.");
- }
- private void StoryLoop()
- {
- //Debug.Log(wait);
- if(wait) return;
- // Read all the content until we can't continue any more
- if (story.canContinue) {
- // Continue gets the next line of the story
- string text = story.Continue ();
- // This removes any white space from the text.
- text = text.Trim();
- // Create StoryStepData
- StoryStepData storyStep = new StoryStepData(StoryStepType.Line, text, story.currentTags, null);
- EventManager.broadcast.Trigger(name, storyStep);
- // Display the text if log is enabled
- if(logText) Debug.Log(storyStep.text);
- }
- else if( story.currentChoices.Count > 0 )
- {
- List<string> choices = new List<string>();
- for (int i = 0; i < story.currentChoices.Count; ++i)
- {
- Choice choice = story.currentChoices [i];
- choices.Add(choice.text);
- if(logText) Debug.Log($"Choice {i + 1}. {choice.text}");
- }
- StoryStepData storyStep = new StoryStepData(StoryStepType.Branch, "", story.currentTags, choices);
- EventManager.broadcast.Trigger(name, storyStep);
- wait = true;
- }
- else Stop();
- }
- private void SelectStoryBranch(StoryStepData storyStep)
- {
- if(storyStep.category == StoryStepType.Path)
- {
- story.ChooseChoiceIndex (storyStep.path);
- wait = false;
- StoryLoop();
- }
- }
- static Subject<StoryStepData> subject;
- public static IObservable<StoryStepData> Lines()
- {
- if(subject == null) subject = new Subject<StoryStepData>();
- return subject.AsObservable();
- }
- private void PublishStorylineToObservers(StoryStepData storyStep)
- {
- if(subject != null) subject.OnNext(storyStep);
- }
- public void JumpToPath(string path)
- {
- if(story != null)
- {
- if(logText) Debug.Log($"Jumping to story knot \"{path}\"");
- story.ChoosePathString(path);
- wait = false;
- }
- }
- #region ExternalStoryFunctions
- private void Wait(int time)
- {
- wait = true;
- Timer.Execute(time, () => wait = false);
- }
- private void EnableGameObject(string name)
- {
- for (int i = 0; i < storyObjects.Count; i++)
- {
- if(storyObjects[i].name == name) storyObjects[i].instance.SetActive(true);
- }
- }
- private void DisableGameObject(string name)
- {
- for (int i = 0; i < storyObjects.Count; i++)
- {
- if(storyObjects[i].name == name) storyObjects[i].instance.SetActive(false);
- }
- }
- #endregion
- }
- }
|