using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using Sirenix.OdinInspector; using KairoEngine.Core; using KairoEngine.Core.ModuleSystem; using Ink.Runtime; namespace KairoEngine.StorySystem { public enum StoryInitType { OnLoad, OnEvent, None } [Serializable, HideReferenceObjectPicker] public class StoryObject : System.Object { [HorizontalGroup("line", 0.3f), HideLabel] public string name; [HorizontalGroup("line", 0.7f), HideLabel, NonSerialized] public GameObject prefab; [HideInInspector, NonSerialized] public GameObject instance; } [Serializable, HideReferenceObjectPicker] public class StorySystemModule : GameModuleBase { public override string name => "Story Module"; [FoldoutGroup("@name"), ShowInInspector, NonSerialized] public TextAsset inkJSONAsset = null; [FoldoutGroup("@name")] public string storyName = "Storyline"; [FoldoutGroup("@name")] public bool showStoryLog = false; [FoldoutGroup("@name")] public int lineInverval = 250; [FoldoutGroup("@name"), LabelText("Start")] public StoryInitType startType; [FoldoutGroup("@name"), ShowIf("@startType == StoryInitType.OnEvent")] public string eventStartName = "StartStory"; [FoldoutGroup("@name"), Space] public List storyObjects = new List(); [SerializeField, HideInInspector] private int storyObjectsCount = 0; private StoryController storyController; private Transform storyObjectsContainer = null; public StorySystemModule(GameConfig config) : base(config) { this.gameConfig = config; this.className = this.GetType().AssemblyQualifiedName; this.typeName = "StorySystemModule"; } public override void Load(Transform parent) { if(storyObjects.Count > 0) storyObjectsContainer = new GameObject("StoryObjects").transform; if(storyObjectsContainer != null) storyObjectsContainer.transform.parent = parent; if(startType == StoryInitType.OnLoad) LoadStory(storyObjectsContainer); else if(startType == StoryInitType.OnEvent) GenericEvents.StartListening(eventStartName, () => LoadStory(storyObjectsContainer)); } private void LoadStory(Transform parent) { if(inkJSONAsset != null) storyController = new StoryController(inkJSONAsset, storyName, storyObjects, parent, showStoryLog, lineInverval); else Debug.LogError($"Missing Ink Story asset in StorySystemModule"); if(storyController != null) storyController.Start(); } public override void Reset() { showStoryLog = false; inkJSONAsset = null; storyController = null; } public override void Destroy() { if(storyController != null) storyController.Stop(); if(startType == StoryInitType.OnEvent) GenericEvents.StopListening(eventStartName, () => LoadStory(storyObjectsContainer)); } public static StorySystemModule JSONToStorySystemModule(string data) { try { return JsonUtility.FromJson(data); } catch (System.Exception e) { Debug.LogError($"Could not deserialize StorySystemModule: \n{e}"); return new StorySystemModule(null); } } public override void OnBeforeSerialize(ObjectSerializer serializer) { if(inkJSONAsset) serializer.objects.Add("inkJSONAsset", inkJSONAsset); if(storyObjectsContainer != null) serializer.gameObjecs.Add("storyObjectsContainer", storyObjectsContainer.gameObject); if(storyController != null) serializer.objects.Add("storyController", storyController); storyObjectsCount = storyObjects.Count; for (int i = 0; i < storyObjects.Count; i++) { serializer.objects.Add($"storyObjects_{i}", storyObjects[i]); } } public override void OnBeforeDeserialize(ObjectSerializer serializer) { // inkJSONAsset object obj = null; serializer.objects.TryGetValue("inkJSONAsset", out obj); if(obj != null) inkJSONAsset = (TextAsset)obj; // storyObjectsContainer GameObject gameObject = null; serializer.gameObjecs.TryGetValue("storyObjectsContainer", out gameObject); if(gameObject != null) storyObjectsContainer = gameObject.transform; // storyController obj = null; serializer.objects.TryGetValue("storyController", out obj); if(obj != null) storyController = (StoryController)obj; // storyObjects for (int i = 0; i < storyObjectsCount; i++) { obj = null; serializer.objects.TryGetValue($"storyObjects_{i}", out obj); if(obj != null) storyObjects.Add((StoryObject)obj); } } } }