using System.Collections; using System.Collections.Generic; using UnityEngine; using Yarn.Unity; using UnityEngine.SceneManagement; public class YarnCommands : MonoBehaviour { static YarnCommands instance; public AnimationCurve ease_in_out; private void Start() { if (instance != null && instance != this) { Destroy(gameObject); return; } else { instance = this; DontDestroyOnLoad(gameObject); } if (GameObject.FindObjectOfType() == null) Debug.LogError("Error : You might be missing a 'Dialogue' gameobject."); } [YarnCommand("DebugLog")] public void DebugLog(string debug_msg) { Debug.Log(debug_msg); } [YarnCommand("quit")] public void quit() { Application.Quit(); } [YarnCommand("camera_warp_target")] public void camera_move(string gameobject_name) { GameObject target = GameObject.Find(gameobject_name); if(target == null) { Debug.LogError("Yarn command \"camera_move\" did not provide the name of a gameobject."); return; } Camera.main.transform.position = target.transform.position; Camera.main.transform.rotation = target.transform.rotation; } [YarnCommand("warp_gameobject_position_rotation")] public void warp_gameobject_position_rotation(string gameobject_path, string x_str, string y_str, string z_str, string xr_str, string yr_str, string zr_str) { if(gameobject_path == null || gameobject_path == "") { Debug.LogError("[YarnCommands.warp_gameobject_position_rotation] Failed to provide a gameobject path."); return; } GameObject target = GetGameObjectAtHierarchyPath(gameobject_path); if(target == null) { Debug.LogError("[YarnCommands.warp_gameobject_position_rotation] Failed to find gameobject with path [" + gameobject_path + "]"); return; } float x = target.transform.localPosition.x; float y = target.transform.localPosition.y; float z = target.transform.localPosition.z; float xr = target.transform.localRotation.eulerAngles.x; float yr = target.transform.localRotation.eulerAngles.y; float zr = target.transform.localRotation.eulerAngles.z; float.TryParse(x_str, out x); float.TryParse(y_str, out y); float.TryParse(z_str, out z); float.TryParse(xr_str, out xr); float.TryParse(yr_str, out yr); float.TryParse(zr_str, out zr); target.transform.localPosition = new Vector3(x, y, z); Quaternion q = new Quaternion(); q.eulerAngles = new Vector3(xr, yr, zr); target.transform.localRotation = q; } /* One string param expected (name of position target gameobject) */ [YarnCommand("camera_ease_target")] public void camera_ease_target(string gameobject_name) { float duration_sec = 1.0f; GameObject target = GameObject.Find(gameobject_name); if(target == null) { Debug.LogError("Yarn Command camera_ease_target was provided a target gameobject name of [" + gameobject_name + "] but no gameobject with this name exists at the root of the scene hierarchy."); return; } //foreach (string parameter in parameters) // Debug.Log("[ PARAMETER" + parameter + "]"); StartCoroutine(_ChangePositionOverTime(Camera.main.transform, target.transform, duration_sec, ease_in_out, null)); } [YarnCommand("camera_warp_position")] public void camera_warp(string x_str, string y_str, string z_str, string xr_str, string yr_str, string zr_str) { float x = Camera.main.transform.position.x; float y = Camera.main.transform.position.y; float z = Camera.main.transform.position.z; float xr = Camera.main.transform.rotation.eulerAngles.x; float yr= Camera.main.transform.rotation.eulerAngles.y; float zr = Camera.main.transform.rotation.eulerAngles.z; float.TryParse(x_str, out x); float.TryParse(y_str, out y); float.TryParse(z_str, out z); float.TryParse(xr_str, out x); float.TryParse(yr_str, out y); float.TryParse(zr_str, out z); Camera.main.transform.position = new Vector3(x, y, z); Quaternion q = new Quaternion(); q.eulerAngles = new Vector3(xr, yr, zr); Camera.main.transform.rotation = q; } [YarnCommand("restart_current_scene")] public void restart_current_scene() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } [YarnCommand("change_scene")] public void change_scene(string scene_name) { SceneManager.LoadScene(scene_name); } [YarnCommand("activate_gameobject")] public void activate_gameobject(string gameobject_path) { Debug.Log("ACTIVATE [" + gameobject_path + "]"); GameObject target_gameobject = GetGameObjectAtHierarchyPath(gameobject_path); if(target_gameobject == null) { Debug.LogError("[YarnCommands.activate_gameobject] Failed to locate gameobject in scene at [" + gameobject_path + "]"); return; } target_gameobject.SetActive(true); } [YarnCommand("deactivate_gameobject")] public void deactivate_gameobject(string gameobject_path) { GameObject target_gameobject = GetGameObjectAtHierarchyPath(gameobject_path); if (target_gameobject == null) { Debug.LogError("[YarnCommands.deactivate_gameobject] Failed to locate gameobject in scene at [" + gameobject_path + "]"); return; } target_gameobject.SetActive(false); } GameObject GetGameObjectAtHierarchyPath(string gameobject_hierarchy_path) { string[] path_elements = gameobject_hierarchy_path.Split('/'); if (path_elements.Length <= 0) { Debug.LogError("Failing (split) hierarchy path search for [" + gameobject_hierarchy_path + "]"); return null; } GameObject g = FindGameObjectFromAll(path_elements[0]); if (g == null) { Debug.LogError("Failing (first find) hierarchy path search for [" + gameobject_hierarchy_path + "]"); return null; } Transform current_t = g.transform; int path_index = 1; while (path_index < path_elements.Length) { Transform new_t = current_t.Find(path_elements[path_index]); if (new_t == null) break; current_t = new_t; path_index++; } return current_t.gameObject; } static GameObject FindGameObjectFromAll(string name) { GameObject[] all_scene_game_objects = GameObject.FindObjectsOfType(true); foreach(GameObject g in all_scene_game_objects) { if (g.name == name) return g; } return null; } [YarnCommand("play_audio_clip")] public void play_audio_clip(string audio_clip_path) { Debug.Log("PLAY AUDIO CLIP " + audio_clip_path); AudioClip clip = Resources.Load(audio_clip_path); if(clip == null) { Debug.LogError("Yarn command \"play_audio_clip\" could not find audio clip in a resources folder with path [" + audio_clip_path + "]"); return; } AudioSource.PlayClipAtPoint(clip, Camera.main.transform.position); } static GameObject GetAudioSystem() { GameObject audio_system = GameObject.Find("_AudioSystem"); if(audio_system == null) { audio_system = new GameObject(); audio_system.name = "_AudioSystem"; GameObject.DontDestroyOnLoad(audio_system); } return audio_system; } static Dictionary audio_tracks = new Dictionary(); [YarnCommand("play_audio_track")] public void play_audio_track(string audio_clip_path, string desired_volume_str) { string track_name = audio_clip_path; float desired_volume = float.Parse(desired_volume_str); /* Get audio track */ GameObject audio_system = GetAudioSystem(); AudioSource[] audio_sources = audio_system.GetComponents(); AudioSource audio_track = null; if (audio_tracks.ContainsKey(track_name)) { audio_track = audio_tracks[track_name]; } else { audio_track = audio_system.AddComponent(); audio_tracks[track_name] = audio_track; audio_track.volume = 0.0f; audio_track.bypassEffects = true; audio_track.loop = true; } /* Get clip */ AudioClip clip = Resources.Load(audio_clip_path); if (clip == null) { Debug.LogError("Yarn command \"play_audio_track\" could not find audio clip in a resources folder with path [" + audio_clip_path + "]"); return; } /* Play clip */ if(clip != audio_track.clip) audio_track.clip = clip; if(!audio_track.isPlaying) audio_track.Play(); /* Fade volume */ StartCoroutine(_ChangeAudioSourceVolumeOverTime(audio_track, desired_volume, 1.0f)); } /* One string param expected, representing desired density */ [YarnCommand("set_fog_density")] public void set_fog_density(string[] parameters, System.Action onComplete) { if(parameters.Length <= 1 || parameters[1] == null || parameters[1].Trim() == "") { Debug.LogError("Yarn Command set_fog_density was not provided with a density parameter."); onComplete(); return; } //foreach (string parameter in parameters) // Debug.Log("[ PARAMETER" + parameter + "]"); StartCoroutine(_ChangeFogDensityOverTime(float.Parse(parameters[1]), onComplete)); } IEnumerator _ChangeFogDensityOverTime(float desired_fog_density, System.Action finished_callback) { float duration_sec = 1.0f; float initial_time = Time.time; float progress = (Time.time - initial_time) / duration_sec; RenderSettings.fog = true; float initial_fog_density = RenderSettings.fogDensity; while (progress < 1.0f) { progress = (Time.time - initial_time) / duration_sec; RenderSettings.fogDensity = Mathf.Lerp(initial_fog_density, desired_fog_density, progress); yield return null; } RenderSettings.fogDensity = desired_fog_density; finished_callback(); } IEnumerator _ChangePositionOverTime(Transform target_obj, Transform dest_obj, float duration_sec, AnimationCurve ease, System.Action finished_callback) { float initial_time = Time.time; float progress = Time.time - initial_time / duration_sec; Vector3 initial_position = target_obj.position; Quaternion initial_rotation = target_obj.rotation; while(progress < 1.0f) { progress = Time.time - initial_time / duration_sec; float effective_progress = progress; if (ease != null) effective_progress = ease.Evaluate(effective_progress); target_obj.position = Vector3.LerpUnclamped(initial_position, dest_obj.position, effective_progress); target_obj.rotation = Quaternion.SlerpUnclamped(initial_rotation, dest_obj.rotation, effective_progress); yield return null; } target_obj.position = Vector3.LerpUnclamped(initial_position, dest_obj.position, 1.0f); target_obj.rotation = Quaternion.SlerpUnclamped(initial_rotation, dest_obj.rotation, 1.0f); if(finished_callback != null) finished_callback(); } IEnumerator _ChangeAudioSourceVolumeOverTime(AudioSource target, float desired_volume, float duration_sec) { float initial_time = Time.time; float progress = (Time.time - initial_time) / duration_sec; float initial_volume = target.volume; while (progress < 1.0f) { progress = (Time.time - initial_time) / duration_sec; target.volume = Mathf.Lerp(initial_volume, desired_volume, progress); yield return null; } target.volume = desired_volume; } }